summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp650
-rw-r--r--OWNERS1
-rw-r--r--ProtoLibraries.bp247
-rw-r--r--StubLibraries.bp88
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java3
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl2
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java45
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java1
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/stats/LoggerInstanceManager.java131
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java118
-rw-r--r--apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java5
-rw-r--r--apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java3
-rw-r--r--apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java6
-rw-r--r--apex/media/framework/lint-baseline.xml312
-rw-r--r--api/Android.bp3
-rw-r--r--boot/Android.bp45
-rw-r--r--core/api/current.txt46
-rw-r--r--core/api/module-lib-current.txt4
-rw-r--r--core/api/system-current.txt16
-rw-r--r--core/api/test-current.txt41
-rw-r--r--core/java/Android.bp326
-rw-r--r--core/java/android/app/Activity.java22
-rw-r--r--core/java/android/app/ActivityOptions.java25
-rw-r--r--core/java/android/app/ActivityTaskManager.java45
-rw-r--r--core/java/android/app/ActivityThread.java7
-rw-r--r--core/java/android/app/ContextImpl.java5
-rw-r--r--core/java/android/app/IActivityTaskManager.aidl34
-rw-r--r--core/java/android/app/INotificationManager.aidl2
-rw-r--r--core/java/android/app/Notification.java18
-rw-r--r--core/java/android/app/SystemServiceRegistry.java13
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java58
-rw-r--r--core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java2
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl4
-rw-r--r--core/java/android/app/servertransaction/LaunchActivityItem.java20
-rw-r--r--core/java/android/companion/CompanionDeviceManager.java8
-rw-r--r--core/java/android/companion/ICompanionDeviceManager.aidl2
-rw-r--r--core/java/android/content/ContentProvider.java2
-rw-r--r--core/java/android/content/Context.java10
-rw-r--r--core/java/android/content/Intent.java10
-rw-r--r--core/java/android/content/pm/AppSearchShortcutInfo.java262
-rw-r--r--core/java/android/content/pm/DataLoaderParams.java17
-rw-r--r--core/java/android/content/pm/PackageInstaller.java11
-rw-r--r--core/java/android/content/pm/PackageManager.java16
-rw-r--r--core/java/android/content/pm/ShortcutInfo.java8
-rw-r--r--core/java/android/hardware/face/FaceSensorPropertiesInternal.java3
-rw-r--r--core/java/android/hardware/fingerprint/IUdfpsHbmListener.aidl7
-rw-r--r--core/java/android/hardware/input/IInputManager.aidl4
-rw-r--r--core/java/android/hardware/input/InputDeviceVibratorManager.java4
-rw-r--r--core/java/android/hardware/input/InputManager.java4
-rw-r--r--core/java/android/net/IpSecAlgorithm.java2
-rw-r--r--core/java/android/os/BatteryStatsManager.java6
-rwxr-xr-xcore/java/android/os/Build.java2
-rw-r--r--core/java/android/os/CombinedVibration.aidl (renamed from core/java/android/os/CombinedVibrationEffect.aidl)2
-rw-r--r--core/java/android/os/CombinedVibration.java (renamed from core/java/android/os/CombinedVibrationEffect.java)154
-rw-r--r--core/java/android/os/FileUtils.java16
-rw-r--r--core/java/android/os/IHintManager.aidl33
-rw-r--r--core/java/android/os/IHintSession.aidl25
-rw-r--r--core/java/android/os/IVibratorManagerService.aidl6
-rw-r--r--core/java/android/os/PerformanceHintManager.java226
-rw-r--r--core/java/android/os/SystemVibrator.java4
-rw-r--r--core/java/android/os/SystemVibratorManager.java8
-rw-r--r--core/java/android/os/UserHandle.java9
-rw-r--r--core/java/android/os/VibratorManager.java16
-rw-r--r--core/java/android/permission/AdminPermissionControlParams.java5
-rw-r--r--core/java/android/provider/Settings.java40
-rw-r--r--core/java/android/service/dataloader/DataLoaderService.java62
-rw-r--r--core/java/android/service/displayhash/DisplayHashParams.java45
-rw-r--r--core/java/android/service/resumeonreboot/OWNERS2
-rw-r--r--core/java/android/service/resumeonreboot/ResumeOnRebootService.java4
-rw-r--r--core/java/android/view/Choreographer.java2
-rw-r--r--core/java/android/view/FrameMetrics.java23
-rw-r--r--core/java/android/view/IWindowManager.aidl47
-rw-r--r--core/java/android/view/InputDevice.java2
-rw-r--r--core/java/android/view/InsetsController.java4
-rw-r--r--core/java/android/view/View.java43
-rw-r--r--core/java/android/view/ViewGroup.java11
-rw-r--r--core/java/android/view/WindowManager.java24
-rw-r--r--core/java/android/view/translation/TranslationManager.java3
-rw-r--r--core/java/android/view/translation/UiTranslationController.java2
-rw-r--r--core/java/android/widget/AbsListView.java3
-rw-r--r--core/java/android/widget/EdgeEffect.java14
-rw-r--r--core/java/android/widget/HorizontalScrollView.java4
-rw-r--r--core/java/android/window/TransitionInfo.java3
-rw-r--r--core/java/android/window/WindowContext.java13
-rw-r--r--core/java/android/window/WindowContextController.java69
-rw-r--r--core/java/com/android/internal/os/BinderLatencyBuckets.java91
-rw-r--r--core/java/com/android/internal/os/BinderLatencyObserver.java57
-rw-r--r--core/java/com/android/internal/os/ZygoteCommandBuffer.java2
-rw-r--r--core/java/com/android/internal/security/VerityUtils.java2
-rw-r--r--core/java/com/android/server/SystemConfig.java8
-rw-r--r--core/jni/android_view_SurfaceControl.cpp4
-rw-r--r--core/res/AndroidManifest.xml6
-rw-r--r--core/res/res/color/surface_light.xml2
-rw-r--r--core/res/res/values-af/strings.xml19
-rw-r--r--core/res/res/values-am/strings.xml19
-rw-r--r--core/res/res/values-ar/strings.xml21
-rw-r--r--core/res/res/values-as/strings.xml21
-rw-r--r--core/res/res/values-az/strings.xml35
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml19
-rw-r--r--core/res/res/values-be/strings.xml27
-rw-r--r--core/res/res/values-bg/strings.xml19
-rw-r--r--core/res/res/values-bn/strings.xml23
-rw-r--r--core/res/res/values-bs/strings.xml25
-rw-r--r--core/res/res/values-ca/strings.xml19
-rw-r--r--core/res/res/values-cs/strings.xml21
-rw-r--r--core/res/res/values-da/strings.xml19
-rw-r--r--core/res/res/values-de/strings.xml31
-rw-r--r--core/res/res/values-el/strings.xml19
-rw-r--r--core/res/res/values-en-rAU/strings.xml19
-rw-r--r--core/res/res/values-en-rCA/strings.xml19
-rw-r--r--core/res/res/values-en-rGB/strings.xml19
-rw-r--r--core/res/res/values-en-rIN/strings.xml19
-rw-r--r--core/res/res/values-en-rXC/strings.xml19
-rw-r--r--core/res/res/values-es-rUS/strings.xml21
-rw-r--r--core/res/res/values-es/strings.xml21
-rw-r--r--core/res/res/values-et/strings.xml19
-rw-r--r--core/res/res/values-eu/strings.xml19
-rw-r--r--core/res/res/values-fa/strings.xml21
-rw-r--r--core/res/res/values-fi/strings.xml21
-rw-r--r--core/res/res/values-fr-rCA/strings.xml21
-rw-r--r--core/res/res/values-fr/strings.xml21
-rw-r--r--core/res/res/values-gl/strings.xml23
-rw-r--r--core/res/res/values-gu/strings.xml23
-rw-r--r--core/res/res/values-hi/strings.xml21
-rw-r--r--core/res/res/values-hr/strings.xml19
-rw-r--r--core/res/res/values-hu/strings.xml19
-rw-r--r--core/res/res/values-hy/strings.xml21
-rw-r--r--core/res/res/values-in/strings.xml23
-rw-r--r--core/res/res/values-is/strings.xml21
-rw-r--r--core/res/res/values-it/strings.xml21
-rw-r--r--core/res/res/values-iw/strings.xml19
-rw-r--r--core/res/res/values-ja/strings.xml21
-rw-r--r--core/res/res/values-ka/strings.xml21
-rw-r--r--core/res/res/values-kk/strings.xml25
-rw-r--r--core/res/res/values-km/strings.xml21
-rw-r--r--core/res/res/values-kn/strings.xml21
-rw-r--r--core/res/res/values-ko/strings.xml21
-rw-r--r--core/res/res/values-ky/strings.xml45
-rw-r--r--core/res/res/values-lo/strings.xml19
-rw-r--r--core/res/res/values-lt/strings.xml21
-rw-r--r--core/res/res/values-lv/strings.xml19
-rw-r--r--core/res/res/values-mk/strings.xml25
-rw-r--r--core/res/res/values-ml/strings.xml21
-rw-r--r--core/res/res/values-mn/strings.xml21
-rw-r--r--core/res/res/values-mr/strings.xml21
-rw-r--r--core/res/res/values-ms/strings.xml21
-rw-r--r--core/res/res/values-my/strings.xml23
-rw-r--r--core/res/res/values-nb/strings.xml19
-rw-r--r--core/res/res/values-ne/strings.xml53
-rw-r--r--core/res/res/values-nl/strings.xml19
-rw-r--r--core/res/res/values-or/strings.xml19
-rw-r--r--core/res/res/values-pa/strings.xml21
-rw-r--r--core/res/res/values-pl/strings.xml25
-rw-r--r--core/res/res/values-pt-rBR/strings.xml19
-rw-r--r--core/res/res/values-pt-rPT/strings.xml19
-rw-r--r--core/res/res/values-pt/strings.xml19
-rw-r--r--core/res/res/values-ro/strings.xml21
-rw-r--r--core/res/res/values-ru/strings.xml19
-rw-r--r--core/res/res/values-si/strings.xml19
-rw-r--r--core/res/res/values-sk/strings.xml21
-rw-r--r--core/res/res/values-sl/strings.xml21
-rw-r--r--core/res/res/values-sq/strings.xml27
-rw-r--r--core/res/res/values-sr/strings.xml19
-rw-r--r--core/res/res/values-sv/strings.xml21
-rw-r--r--core/res/res/values-sw/strings.xml21
-rw-r--r--core/res/res/values-ta/strings.xml19
-rw-r--r--core/res/res/values-te/strings.xml21
-rw-r--r--core/res/res/values-th/strings.xml19
-rw-r--r--core/res/res/values-tl/strings.xml19
-rw-r--r--core/res/res/values-tr/strings.xml19
-rw-r--r--core/res/res/values-uk/strings.xml21
-rw-r--r--core/res/res/values-ur/strings.xml21
-rw-r--r--core/res/res/values-uz/strings.xml15
-rw-r--r--core/res/res/values-vi/strings.xml21
-rw-r--r--core/res/res/values-zh-rCN/strings.xml21
-rw-r--r--core/res/res/values-zh-rHK/strings.xml21
-rw-r--r--core/res/res/values-zh-rTW/strings.xml29
-rw-r--r--core/res/res/values-zu/strings.xml19
-rw-r--r--core/res/res/values/colors_device_defaults.xml6
-rw-r--r--core/res/res/values/config.xml28
-rw-r--r--core/res/res/values/strings.xml19
-rw-r--r--core/res/res/values/symbols.xml11
-rw-r--r--core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/ConnectivitySetupRule.java4
-rw-r--r--core/tests/coretests/src/android/app/admin/OWNERS1
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/TestUtils.java8
-rw-r--r--core/tests/coretests/src/android/app/time/ExternalTimeSuggestionTest.java71
-rw-r--r--core/tests/coretests/src/android/content/ContentProviderTest.java4
-rw-r--r--core/tests/coretests/src/android/net/SntpClientTest.java8
-rw-r--r--core/tests/coretests/src/android/os/CombinedVibrationTest.java (renamed from core/tests/coretests/src/android/os/CombinedVibrationEffectTest.java)80
-rw-r--r--core/tests/coretests/src/android/os/FileUtilsTest.java27
-rw-r--r--core/tests/coretests/src/android/os/PerformanceHintManagerTest.java211
-rw-r--r--core/tests/coretests/src/android/service/timezone/ParcelableTestSupport.java53
-rw-r--r--core/tests/coretests/src/android/service/timezone/TimeZoneProviderSuggestionTest.java107
-rw-r--r--core/tests/coretests/src/android/window/WindowContextControllerTest.java33
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java4
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BinderLatencyBucketsTest.java69
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java76
-rw-r--r--core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java3
-rw-r--r--data/etc/platform.xml3
-rw-r--r--data/etc/services.core.protolog.json18
-rw-r--r--data/keyboards/Vendor_054c_Product_0ce6.kl71
-rw-r--r--data/keyboards/Vendor_0957_Product_0001.idc1
-rw-r--r--data/keyboards/Vendor_0957_Product_0001.kl2
-rw-r--r--data/keyboards/Vendor_248a_Product_8266.idc1
-rw-r--r--graphics/java/android/graphics/FrameInfo.java8
-rw-r--r--graphics/java/android/graphics/HardwareRenderer.java68
-rw-r--r--libs/WindowManager/Shell/lint-baseline.xml5471
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java45
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java20
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java296
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java423
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java36
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java12
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java25
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java80
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java342
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java32
-rw-r--r--libs/hwui/Android.bp1
-rw-r--r--libs/hwui/FrameInfo.cpp29
-rw-r--r--libs/hwui/FrameInfo.h3
-rw-r--r--libs/hwui/Properties.cpp7
-rw-r--r--libs/hwui/Properties.h17
-rw-r--r--libs/hwui/SkiaInterpolator.cpp273
-rw-r--r--libs/hwui/SkiaInterpolator.h119
-rw-r--r--libs/hwui/jni/Interpolator.cpp16
-rw-r--r--libs/hwui/jni/android_graphics_HardwareRenderer.cpp95
-rw-r--r--libs/hwui/renderthread/DrawFrameTask.cpp29
-rw-r--r--libs/hwui/renderthread/DrawFrameTask.h6
-rw-r--r--libs/hwui/renderthread/RenderProxy.cpp6
-rw-r--r--libs/hwui/renderthread/RenderProxy.h2
-rw-r--r--libs/hwui/thread/CommonPool.cpp26
-rw-r--r--libs/hwui/thread/CommonPool.h5
-rw-r--r--media/java/android/media/AudioDeviceInfo.java39
-rw-r--r--media/java/android/media/AudioManager.java11
-rw-r--r--media/java/android/media/AudioSystem.java13
-rw-r--r--media/java/android/media/MediaCodec.java30
-rw-r--r--native/android/surface_control.cpp29
-rw-r--r--packages/Android.bp28
-rw-r--r--packages/Connectivity/framework/Android.bp1
-rw-r--r--packages/Connectivity/framework/api/module-lib-current.txt10
-rw-r--r--packages/Connectivity/framework/api/system-current.txt4
-rw-r--r--packages/Connectivity/framework/lint-baseline.xml48
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java18
-rw-r--r--packages/Connectivity/framework/src/android/net/TcpRepairWindow.java3
-rw-r--r--packages/Connectivity/framework/src/android/net/UidRange.java4
-rw-r--r--packages/Connectivity/service/lint-baseline.xml37
-rw-r--r--packages/SettingsLib/ActionBarShadow/lint-baseline.xml37
-rw-r--r--packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml26
-rw-r--r--packages/SettingsLib/AdaptiveIcon/lint-baseline.xml81
-rw-r--r--packages/SettingsLib/BannerMessagePreference/lint-baseline.xml37
-rw-r--r--packages/SettingsLib/BarChartPreference/lint-baseline.xml15
-rw-r--r--packages/SettingsLib/EmergencyNumber/lint-baseline.xml92
-rw-r--r--packages/SettingsLib/HelpUtils/lint-baseline.xml15
-rw-r--r--packages/SettingsLib/MainSwitchPreference/lint-baseline.xml48
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/layout-v31/main_switch_bar.xml75
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml84
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml2
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/values-sw600dp/dmiens.xml22
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/values-sw720dp-land/dmiens.xml23
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/values-sw720dp/dmiens.xml23
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/values/colors.xml3
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml4
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/values/styles.xml6
-rw-r--r--packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java32
-rw-r--r--packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java4
-rw-r--r--packages/SettingsLib/ProgressBar/lint-baseline.xml15
-rw-r--r--packages/SettingsLib/RestrictedLockUtils/lint-baseline.xml26
-rw-r--r--packages/SettingsLib/SettingsSpinner/lint-baseline.xml15
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-v31/dimens.xml2
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml13
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values/themes.xml2
-rw-r--r--packages/SettingsLib/Tile/lint-baseline.xml81
-rw-r--r--packages/SettingsLib/Utils/lint-baseline.xml15
-rw-r--r--packages/SettingsLib/lint-baseline.xml895
-rw-r--r--packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java18
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java128
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java180
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java3
-rw-r--r--packages/SystemUI/Android.bp2
-rw-r--r--packages/SystemUI/AndroidManifest.xml4
-rw-r--r--packages/SystemUI/animation/Android.bp44
-rw-r--r--packages/SystemUI/animation/AndroidManifest.xml22
-rw-r--r--packages/SystemUI/animation/res/interpolator/launch_animation_interpolator_x.xml18
-rw-r--r--packages/SystemUI/animation/res/interpolator/launch_animation_interpolator_y.xml18
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt (renamed from packages/SystemUI/plugin/src/com/android/systemui/plugins/animation/ActivityLaunchAnimator.kt)76
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt (renamed from packages/SystemUI/plugin/src/com/android/systemui/plugins/animation/GhostedViewLaunchAnimatorController.kt)22
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/Interpolators.java (renamed from packages/SystemUI/src/com/android/systemui/Interpolators.java)15
-rw-r--r--packages/SystemUI/plugin/Android.bp1
-rw-r--r--packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java18
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java2
-rw-r--r--packages/SystemUI/res-keyguard/font/clock.xml3
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml51
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml1
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml7
-rw-r--r--packages/SystemUI/res-keyguard/values/attrs.xml1
-rw-r--r--packages/SystemUI/res-keyguard/values/dimens.xml4
-rw-r--r--packages/SystemUI/res-keyguard/values/styles.xml4
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_01_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_02_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_03_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_04_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_05_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_06_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_07_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_08_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_09_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_10_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_11_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_12_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_13_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_14_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_15_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_16_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_17_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging__dot_18_pivot_animation.xml27
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_10_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_11_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_12_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_13_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_14_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_15_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_16_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_17_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_18_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_1_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_2_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_3_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_4_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_5_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_6_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_7_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_8_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_ellipse_path_9_animation.xml28
-rw-r--r--packages/SystemUI/res/anim/wireless_charging_null_1_animation.xml28
-rw-r--r--packages/SystemUI/res/drawable/bg_smartspace_media_item.xml21
-rw-r--r--packages/SystemUI/res/drawable/brightness_mirror_background.xml2
-rw-r--r--packages/SystemUI/res/drawable/brightness_progress_drawable.xml2
-rw-r--r--packages/SystemUI/res/drawable/brightness_progress_full_drawable.xml3
-rw-r--r--packages/SystemUI/res/drawable/circle_wallet_primary_56dp.xml (renamed from packages/SystemUI/res/drawable/circle_wallet_primary_50dp.xml)4
-rw-r--r--packages/SystemUI/res/drawable/circle_wallet_secondary_56dp.xml23
-rw-r--r--packages/SystemUI/res/drawable/ic_wallet_lockscreen.xml37
-rw-r--r--packages/SystemUI/res/drawable/notification_guts_bg.xml5
-rw-r--r--packages/SystemUI/res/drawable/notification_material_bg.xml3
-rw-r--r--packages/SystemUI/res/drawable/qs_background_primary.xml2
-rw-r--r--packages/SystemUI/res/drawable/qs_customize_tile_decoration.xml2
-rw-r--r--packages/SystemUI/res/drawable/qs_customizer_background_primary.xml2
-rw-r--r--packages/SystemUI/res/drawable/qs_customizer_toolbar.xml2
-rw-r--r--packages/SystemUI/res/drawable/qs_dialog_bg.xml (renamed from packages/SystemUI/res/drawable/privacy_dialog_bg.xml)2
-rw-r--r--packages/SystemUI/res/drawable/wallet_action_button_bg.xml (renamed from packages/SystemUI/res/drawable/wallet_button.xml)0
-rw-r--r--packages/SystemUI/res/drawable/wallet_app_button_bg.xml25
-rw-r--r--packages/SystemUI/res/drawable/wallet_lockscreen_bg.xml33
-rw-r--r--packages/SystemUI/res/drawable/wireless_charging.xml300
-rw-r--r--packages/SystemUI/res/drawable/wireless_charging_animation.xml133
-rw-r--r--packages/SystemUI/res/layout/brightness_mirror.xml1
-rw-r--r--packages/SystemUI/res/layout/keyguard_bottom_area.xml8
-rw-r--r--packages/SystemUI/res/layout/long_screenshot.xml1
-rw-r--r--packages/SystemUI/res/layout/media_smartspace_recommendations.xml87
-rw-r--r--packages/SystemUI/res/layout/people_space_placeholder_layout.xml1
-rw-r--r--packages/SystemUI/res/layout/people_tile_large_empty.xml1
-rw-r--r--packages/SystemUI/res/layout/people_tile_large_with_content.xml2
-rw-r--r--packages/SystemUI/res/layout/people_tile_medium_empty.xml1
-rw-r--r--packages/SystemUI/res/layout/people_tile_medium_with_content.xml2
-rw-r--r--packages/SystemUI/res/layout/people_tile_small.xml2
-rw-r--r--packages/SystemUI/res/layout/privacy_dialog.xml2
-rw-r--r--packages/SystemUI/res/layout/privacy_dialog_item.xml1
-rw-r--r--packages/SystemUI/res/layout/wallet_fullscreen.xml33
-rw-r--r--packages/SystemUI/res/layout/wireless_charging_layout.xml8
-rw-r--r--packages/SystemUI/res/values-night/colors.xml5
-rw-r--r--packages/SystemUI/res/values-sw600dp-land/dimens.xml5
-rw-r--r--packages/SystemUI/res/values/attrs.xml2
-rw-r--r--packages/SystemUI/res/values/colors.xml3
-rw-r--r--packages/SystemUI/res/values/dimens.xml27
-rw-r--r--packages/SystemUI/res/values/flags.xml2
-rw-r--r--packages/SystemUI/res/values/strings.xml20
-rw-r--r--packages/SystemUI/res/values/styles.xml22
-rw-r--r--packages/SystemUI/res/xml/media_recommendation.xml97
-rw-r--r--packages/SystemUI/res/xml/people_space_widget_info.xml5
-rw-r--r--packages/SystemUI/shared/lint-baseline.xml675
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java7
-rw-r--r--packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java15
-rw-r--r--packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java47
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java453
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java239
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java23
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java35
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java16
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/LockIconViewController.java4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/TextAnimator.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/BatteryMeterView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/ImageWallpaper.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/ScreenDecorations.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/SwipeHelper.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIFactory.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistOrbContainer.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistOrbView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/HbmTypes.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardDrawable.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/IlluminationDrawable.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/LightSourceDrawable.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt88
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java205
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt135
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaHost.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt33
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt80
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaDataProvider.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/RotationButtonController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonRipple.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java44
-rw-r--r--packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFragment.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/dagger/QSThemedContext.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/CropView.java299
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java81
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java108
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/ExpandAnimationParameters.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PriorityOnboardingDialogController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java95
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java62
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherListView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java72
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java11
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java108
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java170
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/TextAnimatorTest.kt33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/plugins/animation/ActivityLaunchAnimatorTest.kt)10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt42
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt30
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java52
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt21
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java142
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java408
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java4
-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.bp16
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java3
-rw-r--r--services/core/java/com/android/server/BinderCallsStatsService.java19
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java16
-rw-r--r--services/core/java/com/android/server/DropBoxManagerService.java2
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java90
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java3
-rw-r--r--services/core/java/com/android/server/am/CachedAppOptimizer.java10
-rw-r--r--services/core/java/com/android/server/am/ContentProviderHelper.java6
-rw-r--r--services/core/java/com/android/server/appop/HistoricalRegistry.java31
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceInventory.java5
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java4
-rw-r--r--services/core/java/com/android/server/biometrics/AuthSession.java3
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricSensor.java18
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricService.java11
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java3
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java22
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/DetectionConsumer.java24
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceService.java18
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java7
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java102
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java26
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java12
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java16
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java6
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java5
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java4
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintUpdateActiveUserClient.java2
-rw-r--r--services/core/java/com/android/server/connectivity/FullScore.java33
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkAgentInfo.java16
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkOffer.java4
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkRanker.java22
-rw-r--r--services/core/java/com/android/server/connectivity/PermissionMonitor.java6
-rw-r--r--services/core/java/com/android/server/display/DisplayModeDirector.java111
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java17
-rw-r--r--services/core/java/com/android/server/graphics/fonts/FontManagerShellCommand.java55
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecConfig.java2
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java16
-rw-r--r--services/core/java/com/android/server/notification/ManagedServices.java5
-rw-r--r--services/core/java/com/android/server/notification/NASLearnMoreActivity.java51
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java204
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java1
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerServiceUtils.java2
-rw-r--r--services/core/java/com/android/server/pm/ShortcutPackage.java946
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java170
-rw-r--r--services/core/java/com/android/server/pm/ShortcutUser.java4
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java122
-rw-r--r--services/core/java/com/android/server/power/FaceDownDetector.java28
-rw-r--r--services/core/java/com/android/server/power/hint/HintManagerService.java449
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java8
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java30
-rw-r--r--services/core/java/com/android/server/utils/ManagedApplicationService.java3
-rw-r--r--services/core/java/com/android/server/vibrator/InputDeviceDelegate.java4
-rw-r--r--services/core/java/com/android/server/vibrator/Vibration.java72
-rw-r--r--services/core/java/com/android/server/vibrator/VibrationThread.java89
-rw-r--r--services/core/java/com/android/server/vibrator/VibratorManagerService.java63
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java107
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java6
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java150
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java3
-rw-r--r--services/core/java/com/android/server/wm/AppTransitionController.java3
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java26
-rw-r--r--services/core/java/com/android/server/wm/FadeRotationAnimationController.java11
-rw-r--r--services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java2
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java14
-rw-r--r--services/core/java/com/android/server/wm/Letterbox.java62
-rw-r--r--services/core/java/com/android/server/wm/RecentTasks.java5
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimationController.java30
-rw-r--r--services/core/java/com/android/server/wm/SafeActivityOptions.java14
-rw-r--r--services/core/java/com/android/server/wm/Task.java19
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotController.java4
-rw-r--r--services/core/java/com/android/server/wm/Transition.java3
-rw-r--r--services/core/java/com/android/server/wm/WallpaperController.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowContextListenerController.java6
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java217
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerShellCommand.java252
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java75
-rw-r--r--services/core/java/com/android/server/wm/WindowToken.java3
-rw-r--r--services/core/jni/Android.bp7
-rw-r--r--services/core/jni/com_android_server_am_CachedAppOptimizer.cpp68
-rw-r--r--services/core/jni/com_android_server_hint_HintManagerService.cpp166
-rw-r--r--services/core/jni/com_android_server_power_PowerManagerService.cpp2
-rw-r--r--services/core/jni/com_android_server_vibrator_VibratorController.cpp24
-rw-r--r--services/core/jni/onload.cpp2
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java26
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java39
-rw-r--r--services/java/com/android/server/SystemServer.java9
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ActiveServicesTest.java95
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/power/FaceDownDetectorTest.java47
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java98
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java25
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java69
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java41
-rw-r--r--services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java30
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java268
-rw-r--r--services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java43
-rw-r--r--services/tests/servicestests/src/com/android/server/uwb/OWNERS1
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java36
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java116
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java12
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java132
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java241
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InputMethodMenuControllerTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java22
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java7
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java31
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java25
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java16
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java71
-rw-r--r--services/uwb/OWNERS1
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java10
-rw-r--r--tests/net/common/java/android/net/NetworkAgentConfigTest.kt15
-rw-r--r--tests/net/java/android/net/IpSecAlgorithmTest.java6
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java13
-rw-r--r--tests/net/java/com/android/server/connectivity/FullScoreTest.kt2
-rw-r--r--tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java18
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/VibratorManagerServicePermissionTest.java6
-rw-r--r--tests/vcn/java/com/android/server/VcnManagementServiceTest.java6
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java30
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java5
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java31
-rw-r--r--tools/fonts/Android.bp51
-rw-r--r--wifi/OWNERS1
683 files changed, 21984 insertions, 7340 deletions
diff --git a/Android.bp b/Android.bp
index 9e1820e9f6ea..ca014bc7b11c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -14,41 +14,6 @@
// Build the master framework library.
-// Defaults for platform code that runs inside system_server
-java_defaults {
- name: "platform_service_defaults",
- plugins: [
- "error_prone_android_framework",
- ],
- errorprone: {
- javacflags: [
- // "-Xep:AndroidFrameworkBinderIdentity:ERROR",
- "-Xep:AndroidFrameworkCompatChange:ERROR",
- // "-Xep:AndroidFrameworkUid:ERROR",
- // NOTE: only enable to generate local patchfiles
- // "-XepPatchChecks:refaster:frameworks/base/errorprone/refaster/EfficientXml.java.refaster",
- // "-XepPatchLocation:/tmp/refaster/",
- ],
- },
-}
-
-// Defaults for platform apps
-java_defaults {
- name: "platform_app_defaults",
- plugins: [
- "error_prone_android_framework",
- ],
- errorprone: {
- javacflags: [
- // We're less worried about performance in app code
- "-Xep:AndroidFrameworkEfficientCollections:OFF",
- "-Xep:AndroidFrameworkEfficientParcelable:OFF",
- "-Xep:AndroidFrameworkEfficientStrings:OFF",
- "-Xep:AndroidFrameworkEfficientXml:OFF",
- ],
- },
-}
-
// READ ME: ########################################################
//
// When updating this list of aidl files, consider if that aidl is
@@ -306,43 +271,6 @@ java_library {
installable: false,
}
-filegroup {
- name: "framework-jarjar-rules",
- srcs: ["framework-jarjar-rules.txt"],
-}
-
-filegroup {
- name: "libincident_aidl",
- srcs: [
- "core/java/android/os/IIncidentDumpCallback.aidl",
- "core/java/android/os/IIncidentManager.aidl",
- "core/java/android/os/IIncidentReportStatusListener.aidl",
- ],
- path: "core/java",
-}
-
-filegroup {
- name: "libvibrator_aidl",
- srcs: [
- "core/java/android/os/IExternalVibrationController.aidl",
- "core/java/android/os/IExternalVibratorService.aidl",
- ],
- path: "core/java",
-}
-
-filegroup {
- name: "libpowermanager_aidl",
- srcs: [
- "core/java/android/os/Temperature.aidl",
- "core/java/android/os/CoolingDevice.aidl",
- "core/java/android/os/IThermalEventListener.aidl",
- "core/java/android/os/IThermalStatusListener.aidl",
- "core/java/android/os/IThermalService.aidl",
- "core/java/android/os/IPowerManager.aidl",
- ],
- path: "core/java",
-}
-
java_defaults {
name: "framework-minus-apex-defaults",
defaults: ["framework-aidl-export-defaults"],
@@ -363,7 +291,7 @@ java_defaults {
"--core-library",
"--multi-dex",
],
- jarjar_rules: ":framework-jarjar-rules",
+ jarjar_rules: "framework-jarjar-rules.txt",
javac_shard_size: 150,
plugins: [
"view-inspector-annotation-processor",
@@ -460,86 +388,6 @@ platform_compat_config {
src: ":framework-minus-apex",
}
-genrule {
- name: "statslog-framework-java-gen",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --java $(out) --module framework" +
- " --javaPackage com.android.internal.util --javaClass FrameworkStatsLog --worksource",
- out: ["com/android/internal/util/FrameworkStatsLog.java"],
-}
-
-java_library {
- name: "uieventloggerlib",
- srcs: [
- "core/java/com/android/internal/logging/UiEvent.java",
- "core/java/com/android/internal/logging/UiEventLogger.java",
- "core/java/com/android/internal/logging/UiEventLoggerImpl.java",
- "core/java/com/android/internal/logging/InstanceId.java",
- "core/java/com/android/internal/logging/InstanceIdSequence.java",
- ":statslog-framework-java-gen",
- ],
-}
-
-gensrcs {
- name: "framework-javastream-protos",
- depfile: true,
-
- tools: [
- "aprotoc",
- "protoc-gen-javastream",
- "soong_zip",
- ],
-
- cmd: "mkdir -p $(genDir)/$(in) " +
- "&& $(location aprotoc) " +
- " --plugin=$(location protoc-gen-javastream) " +
- " --dependency_out=$(depfile) " +
- " --javastream_out=$(genDir)/$(in) " +
- " -Iexternal/protobuf/src " +
- " -I . " +
- " $(in) " +
- "&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)",
-
- srcs: [
- ":ipconnectivity-proto-src",
- ":libstats_atom_enum_protos",
- ":libtombstone_proto-src",
- "core/proto/**/*.proto",
- "libs/incident/**/*.proto",
- ":service-permission-protos",
- ],
- output_extension: "srcjar",
-}
-
-gensrcs {
- name: "framework-cppstream-protos",
- depfile: true,
-
- tools: [
- "aprotoc",
- "protoc-gen-cppstream",
- ],
-
- cmd: "mkdir -p $(genDir) " +
- "&& $(location aprotoc) " +
- " --plugin=$(location protoc-gen-cppstream) " +
- " --dependency_out=$(depfile) " +
- " --cppstream_out=$(genDir) " +
- " -Iexternal/protobuf/src " +
- " -I . " +
- " $(in)",
-
- srcs: [
- ":ipconnectivity-proto-src",
- ":libstats_atom_enum_protos",
- "core/proto/**/*.proto",
- "libs/incident/**/*.proto",
- ":service-permission-protos",
- ],
-
- output_extension: "proto.h",
-}
-
filegroup {
name: "framework-annotations",
srcs: [
@@ -615,76 +463,6 @@ filegroup {
],
}
-filegroup {
- name: "framework-services-net-module-wifi-shared-srcs",
- srcs: [
- "core/java/android/net/DhcpResults.java",
- "core/java/android/util/LocalLog.java",
- ],
-}
-
-// keep these files in sync with the package/Tethering/jarjar-rules.txt and
-// package/Connectivity/jarjar-rules.txt for the tethering module and connectivity module.
-filegroup {
- name: "framework-connectivity-shared-srcs",
- srcs: [
- "core/java/android/util/IndentingPrintWriter.java",
- "core/java/android/util/LocalLog.java",
- // This should be android.util.IndentingPrintWriter, but it's not available in all branches.
- "core/java/com/android/internal/util/IndentingPrintWriter.java",
- "core/java/com/android/internal/util/IState.java",
- "core/java/com/android/internal/util/MessageUtils.java",
- "core/java/com/android/internal/util/State.java",
- "core/java/com/android/internal/util/StateMachine.java",
- "core/java/com/android/internal/util/WakeupMessage.java",
- ],
-}
-
-// keep these files in sync with the apex/jobscheduler/service jarjar-rules.txt for
-// the jobscheduler module.
-filegroup {
- name: "framework-jobscheduler-shared-srcs",
- srcs: [
- "core/java/com/android/internal/util/ArrayUtils.java",
- "core/java/com/android/internal/util/BitUtils.java",
- "core/java/com/android/internal/util/CollectionUtils.java",
- "core/java/com/android/internal/util/ConcurrentUtils.java",
- "core/java/com/android/internal/util/DumpUtils.java",
- "core/java/com/android/internal/util/FastPrintWriter.java",
- "core/java/com/android/internal/util/FastXmlSerializer.java",
- "core/java/com/android/internal/util/FunctionalUtils.java",
- "core/java/com/android/internal/util/ParseUtils.java",
- "core/java/com/android/internal/util/Preconditions.java",
- "core/java/com/android/internal/util/RingBufferIndices.java",
- "core/java/com/android/internal/util/StatLogger.java",
- "core/java/com/android/internal/util/XmlUtils.java",
- ],
-}
-
-// Keep these files in sync with the apex/permission/jarjar-rules.txt for the permission module.
-filegroup {
- name: "framework-permission-s-shared-srcs",
- srcs: [
- "core/java/com/android/internal/infra/AndroidFuture.java",
- "core/java/com/android/internal/infra/ServiceConnector.java",
- "core/java/com/android/internal/util/Preconditions.java",
- "core/java/com/android/internal/infra/AndroidFuture.aidl",
- "core/java/com/android/internal/infra/IAndroidFuture.aidl",
- "core/java/android/os/HandlerExecutor.java",
- ],
- path: "core/java",
-}
-
-// Keep these files in sync with the apex/permission/jarjar-rules.txt for the permission module.
-filegroup {
- name: "service-permission-shared-srcs",
- srcs: [
- "core/java/android/util/IndentingPrintWriter.java",
- "core/java/com/android/internal/util/dump/DualDumpOutputStream.java",
- ],
- path: "core/java",
-}
-
// Build ext.jar
// ============================================================
java_library {
@@ -699,382 +477,6 @@ java_library {
dxflags: ["--core-library"],
}
-// ==== java proto host library ==============================
-java_library_host {
- name: "platformprotos",
- srcs: [
- ":ipconnectivity-proto-src",
- ":libstats_atom_enum_protos",
- ":libstats_internal_protos",
- ":statsd_internal_protos",
- "cmds/am/proto/instrumentation_data.proto",
- "cmds/statsd/src/**/*.proto",
- "core/proto/**/*.proto",
- "libs/incident/proto/**/*.proto",
- ":service-permission-protos",
- ],
- proto: {
- include_dirs: [
- "external/protobuf/src",
- "frameworks/proto_logging/stats",
- ],
- type: "full",
- },
- // Protos have lots of MissingOverride and similar.
- errorprone: {
- javacflags: ["-XepDisableAllChecks"],
- },
-}
-
-// ==== java proto device library (for test only) ==============================
-java_library {
- name: "platformprotosnano",
- proto: {
- type: "nano",
- output_params: ["store_unknown_fields=true"],
- include_dirs: ["external/protobuf/src"],
- },
- exclude_srcs: [
- "core/proto/android/privacy.proto",
- "core/proto/android/section.proto",
- "core/proto/android/typedef.proto",
- ],
- sdk_version: "9",
- srcs: [
- ":ipconnectivity-proto-src",
- ":libstats_atom_enum_protos",
- "core/proto/**/*.proto",
- "libs/incident/proto/android/os/**/*.proto",
- ":service-permission-protos",
- ],
-}
-
-// ==== java proto device library (for test only) ==============================
-java_library {
- name: "platformprotoslite",
- proto: {
- type: "lite",
- include_dirs: ["external/protobuf/src"],
- },
-
- srcs: [
- ":ipconnectivity-proto-src",
- ":libstats_atom_enum_protos",
- "core/proto/**/*.proto",
- "libs/incident/proto/android/os/**/*.proto",
- ":service-permission-protos",
- ],
- exclude_srcs: [
- "core/proto/android/privacy.proto",
- "core/proto/android/section.proto",
- "core/proto/android/typedef.proto",
- ],
- sdk_version: "core_current",
- // Protos have lots of MissingOverride and similar.
- errorprone: {
- javacflags: ["-XepDisableAllChecks"],
- },
-}
-
-// ==== c++ proto device library ==============================
-cc_defaults {
- name: "libplatformprotos-defaults",
-
- proto: {
- export_proto_headers: true,
- include_dirs: [
- "external/protobuf/src",
- ],
- },
-
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-unused-parameter",
- ],
-
- srcs: [
- ":ipconnectivity-proto-src",
- ":libstats_atom_enum_protos",
- "core/proto/**/*.proto",
- ":service-permission-protos",
- ],
-}
-
-cc_library {
- name: "libplatformprotos",
- defaults: ["libplatformprotos-defaults"],
- host_supported: true,
-
- target: {
- host: {
- proto: {
- type: "full",
- },
- },
- android: {
- proto: {
- type: "lite",
- },
- shared_libs: [
- "libprotobuf-cpp-lite",
- ],
- shared: {
- enabled: false,
- },
- },
- },
-}
-
-// This library is meant for vendor code that needs to output protobuf. It links
-// against the static version of libprotobuf-cpp-lite, for which we can not guarantee
-// binary compatibility.
-cc_library {
- name: "libplatformprotos-static",
- defaults: ["libplatformprotos-defaults"],
- host_supported: false,
-
- // This is okay because this library is only built as a static library. The C++
- // API is not guaranteed. The proto API is guaranteed to be stable via Metrics Council,
- // but is not authorized to be used outside of debugging.
- vendor_available: true,
-
- target: {
- android: {
- proto: {
- type: "lite",
- },
- static_libs: [
- "libprotobuf-cpp-lite",
- ],
- shared: {
- enabled: false,
- },
- },
- },
-}
-
-// This is the full proto version of libplatformprotos. It may only
-// be used by test code that is not shipped on the device.
-cc_library {
- name: "libplatformprotos-test",
- defaults: ["libplatformprotos-defaults"],
- host_supported: false,
-
- target: {
- android: {
- proto: {
- type: "full",
- },
- shared: {
- enabled: false,
- },
- },
- },
-}
-
-filegroup {
- name: "incremental_aidl",
- srcs: [
- "core/java/android/os/incremental/IIncrementalServiceConnector.aidl",
- "core/java/android/os/incremental/IncrementalFileSystemControlParcel.aidl",
- ],
- path: "core/java",
-}
-
-filegroup {
- name: "dataloader_aidl",
- srcs: [
- "core/java/android/content/pm/DataLoaderParamsParcel.aidl",
- "core/java/android/content/pm/DataLoaderType.aidl",
- "core/java/android/content/pm/FileSystemControlParcel.aidl",
- "core/java/android/content/pm/IDataLoader.aidl",
- "core/java/android/content/pm/IDataLoaderManager.aidl",
- "core/java/android/content/pm/InstallationFileParcel.aidl",
- "core/java/android/content/pm/InstallationFileLocation.aidl",
- "core/java/android/content/pm/IDataLoaderStatusListener.aidl",
- "core/java/android/content/pm/IPackageInstallerSessionFileSystemConnector.aidl",
- ],
- path: "core/java",
-}
-
-filegroup {
- name: "incremental_manager_aidl",
- srcs: [
- "core/java/android/os/incremental/IIncrementalService.aidl",
- "core/java/android/os/incremental/IStorageLoadingProgressListener.aidl",
- "core/java/android/os/incremental/IncrementalNewFileParams.aidl",
- "core/java/android/os/incremental/IStorageHealthListener.aidl",
- "core/java/android/os/incremental/PerUidReadTimeouts.aidl",
- "core/java/android/os/incremental/StorageHealthCheckParams.aidl",
- ],
- path: "core/java",
-}
-
-filegroup {
- name: "activity_manager_procstate_aidl",
- srcs: [
- "core/java/android/app/ProcessStateEnum.aidl",
- ],
- path: "core/java",
-}
-
-cc_defaults {
- name: "incremental_default",
- cflags: [
- "-Wall",
- "-Wextra",
- "-Wextra-semi",
- "-Werror",
- "-Wzero-as-null-pointer-constant",
- "-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION",
- ],
- shared_libs: [
- "libbinder",
- "libutils",
- ],
- aidl: {
- include_dirs: [
- "frameworks/native/aidl/binder",
- ],
- export_aidl_headers: true,
- },
-}
-
-cc_library {
- name: "libincremental_aidl-cpp",
- srcs: [
- ":incremental_aidl",
- ],
- defaults: ["incremental_default"],
-}
-
-cc_library {
- name: "libdataloader_aidl-cpp",
- srcs: [
- ":dataloader_aidl",
- ],
- defaults: ["incremental_default"],
- shared_libs: [
- "libincremental_aidl-cpp",
- ],
-}
-
-cc_library {
- name: "libincremental_manager_aidl-cpp",
- srcs: [
- ":incremental_manager_aidl",
- ],
- defaults: ["incremental_default"],
- shared_libs: [
- "libincremental_aidl-cpp",
- "libdataloader_aidl-cpp",
- ],
-}
-
-// Build Rust bindings for PermissionController. Needed by keystore2.
-aidl_interface {
- name: "android.os.permissions_aidl",
- unstable: true,
- local_include_dir: "core/java",
- srcs: [
- "core/java/android/os/IPermissionController.aidl",
- ],
- backend: {
- rust: {
- enabled: true,
- },
- },
-}
-
-python_defaults {
- name: "base_default",
- version: {
- py2: {
- enabled: false,
- embedded_launcher: false,
- },
- py3: {
- enabled: true,
- embedded_launcher: true,
- },
- },
-}
-
-python_binary_host {
- name: "fontchain_linter",
- defaults: ["base_default"],
- main: "tools/fonts/fontchain_linter.py",
- srcs: [
- "tools/fonts/fontchain_linter.py",
- ],
- libs: [
- "fontTools",
- ],
-}
-
-python_binary_host {
- name: "update_font_metadata",
- defaults: ["base_default"],
- main: "tools/fonts/update_font_metadata.py",
- srcs: [
- "tools/fonts/update_font_metadata.py",
- ],
- libs: [
- "fontTools",
- ],
-}
-
-// Avoid including Parcelable classes as we don't want to have two copies of
-// Parcelable cross the libraries. This is used by telephony-common (frameworks/opt/telephony)
-// and TeleService app (packages/services/Telephony).
-filegroup {
- name: "framework-telephony-common-shared-srcs",
- srcs: [
- "core/java/android/os/RegistrantList.java",
- "core/java/android/os/Registrant.java",
- "core/java/android/util/IndentingPrintWriter.java",
- "core/java/android/util/LocalLog.java",
- "core/java/android/util/TimeUtils.java",
- "core/java/com/android/internal/os/SomeArgs.java",
- "core/java/com/android/internal/util/AsyncChannel.java",
- "core/java/com/android/internal/util/AsyncService.java",
- "core/java/com/android/internal/util/BitwiseInputStream.java",
- "core/java/com/android/internal/util/FastXmlSerializer.java",
- "core/java/com/android/internal/util/HexDump.java",
- "core/java/com/android/internal/util/IState.java",
- "core/java/com/android/internal/util/IndentingPrintWriter.java",
- "core/java/com/android/internal/util/Preconditions.java",
- "core/java/com/android/internal/util/State.java",
- "core/java/com/android/internal/util/StateMachine.java",
- "core/java/com/android/internal/util/UserIcons.java",
- ],
-}
-
-// Avoid including Parcelable classes as we don't want to have two copies of
-// Parcelable cross the process.
-filegroup {
- name: "framework-cellbroadcast-shared-srcs",
- srcs: [
- "core/java/android/os/HandlerExecutor.java",
- "core/java/android/util/LocalLog.java",
- "core/java/com/android/internal/util/IState.java",
- "core/java/com/android/internal/util/Preconditions.java",
- "core/java/com/android/internal/util/State.java",
- "core/java/com/android/internal/util/StateMachine.java",
- ],
-}
-
-filegroup {
- name: "framework-ims-common-shared-srcs",
- srcs: [
- "core/java/android/os/RegistrantList.java",
- "core/java/android/os/Registrant.java",
- "core/java/com/android/internal/os/SomeArgs.java",
- "core/java/com/android/internal/util/Preconditions.java",
- ],
-}
-
// utility classes statically linked into framework-wifi and dynamically linked
// into wifi-service
java_library {
@@ -1102,27 +504,6 @@ java_library {
],
}
-// utility classes statically linked into wifi-service
-filegroup {
- name: "framework-wifi-service-shared-srcs",
- srcs: [
- "core/java/android/net/InterfaceConfiguration.java",
- "core/java/android/util/BackupUtils.java",
- "core/java/android/util/Rational.java",
- "core/java/com/android/internal/util/FastXmlSerializer.java",
- "core/java/com/android/internal/util/HexDump.java",
- "core/java/com/android/internal/util/IState.java",
- "core/java/com/android/internal/util/MessageUtils.java",
- "core/java/com/android/internal/util/State.java",
- "core/java/com/android/internal/util/StateMachine.java",
- "core/java/com/android/internal/util/WakeupMessage.java",
- ],
- visibility: [
- "//frameworks/opt/net/wifi/service",
- "//packages/modules/Wifi/service",
- ],
-}
-
// TODO(b/145644363): move this to under StubLibraries.bp or ApiDocs.bp
metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.xml) " +
"--hide-package com.android.server " +
@@ -1156,32 +537,5 @@ filegroup {
build = [
"StubLibraries.bp",
"ApiDocs.bp",
+ "ProtoLibraries.bp",
]
-
-// protolog start
-filegroup {
- name: "protolog-common-src",
- srcs: [
- "core/java/com/android/internal/protolog/common/**/*.java",
- ],
-}
-
-java_library {
- name: "protolog-lib",
- platform_apis: true,
- srcs: [
- "core/java/com/android/internal/protolog/ProtoLogImpl.java",
- "core/java/com/android/internal/protolog/ProtoLogViewerConfigReader.java",
- ":protolog-common-src",
- ],
-}
-
-java_library {
- name: "protolog-groups",
- srcs: [
- "core/java/com/android/internal/protolog/ProtoLogGroup.java",
- ":protolog-common-src",
- ],
-}
-
-// protolog end
diff --git a/OWNERS b/OWNERS
index 710f13e4f568..4970dd122331 100644
--- a/OWNERS
+++ b/OWNERS
@@ -30,3 +30,4 @@ per-file Android.bp = file:platform/build/soong:/OWNERS
per-file Android.mk = file:platform/build/soong:/OWNERS
per-file ApiDocs.bp = file:platform/build/soong:/OWNERS
per-file StubLibraries.bp = file:platform/build/soong:/OWNERS
+per-file ProtoLibraries.bp = file:platform/build/soong:/OWNERS
diff --git a/ProtoLibraries.bp b/ProtoLibraries.bp
new file mode 100644
index 000000000000..14415dbed877
--- /dev/null
+++ b/ProtoLibraries.bp
@@ -0,0 +1,247 @@
+// 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.
+
+gensrcs {
+ name: "framework-javastream-protos",
+ depfile: true,
+
+ tools: [
+ "aprotoc",
+ "protoc-gen-javastream",
+ "soong_zip",
+ ],
+
+ cmd: "mkdir -p $(genDir)/$(in) " +
+ "&& $(location aprotoc) " +
+ " --plugin=$(location protoc-gen-javastream) " +
+ " --dependency_out=$(depfile) " +
+ " --javastream_out=$(genDir)/$(in) " +
+ " -Iexternal/protobuf/src " +
+ " -I . " +
+ " $(in) " +
+ "&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)",
+
+ srcs: [
+ ":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
+ ":libtombstone_proto-src",
+ "core/proto/**/*.proto",
+ "libs/incident/**/*.proto",
+ ":service-permission-protos",
+ ],
+ output_extension: "srcjar",
+}
+
+gensrcs {
+ name: "framework-cppstream-protos",
+ depfile: true,
+
+ tools: [
+ "aprotoc",
+ "protoc-gen-cppstream",
+ ],
+
+ cmd: "mkdir -p $(genDir) " +
+ "&& $(location aprotoc) " +
+ " --plugin=$(location protoc-gen-cppstream) " +
+ " --dependency_out=$(depfile) " +
+ " --cppstream_out=$(genDir) " +
+ " -Iexternal/protobuf/src " +
+ " -I . " +
+ " $(in)",
+
+ srcs: [
+ ":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
+ "core/proto/**/*.proto",
+ "libs/incident/**/*.proto",
+ ":service-permission-protos",
+ ],
+
+ output_extension: "proto.h",
+}
+
+// ==== java proto host library ==============================
+java_library_host {
+ name: "platformprotos",
+ srcs: [
+ ":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
+ ":libstats_internal_protos",
+ ":statsd_internal_protos",
+ "cmds/am/proto/instrumentation_data.proto",
+ "cmds/statsd/src/**/*.proto",
+ "core/proto/**/*.proto",
+ "libs/incident/proto/**/*.proto",
+ ":service-permission-protos",
+ ],
+ proto: {
+ include_dirs: [
+ "external/protobuf/src",
+ "frameworks/proto_logging/stats",
+ ],
+ type: "full",
+ },
+ // Protos have lots of MissingOverride and similar.
+ errorprone: {
+ javacflags: ["-XepDisableAllChecks"],
+ },
+}
+
+// ==== java proto device library (for test only) ==============================
+java_library {
+ name: "platformprotosnano",
+ proto: {
+ type: "nano",
+ output_params: ["store_unknown_fields=true"],
+ include_dirs: ["external/protobuf/src"],
+ },
+ exclude_srcs: [
+ "core/proto/android/privacy.proto",
+ "core/proto/android/section.proto",
+ "core/proto/android/typedef.proto",
+ ],
+ sdk_version: "9",
+ srcs: [
+ ":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
+ "core/proto/**/*.proto",
+ "libs/incident/proto/android/os/**/*.proto",
+ ":service-permission-protos",
+ ],
+}
+
+// ==== java proto device library (for test only) ==============================
+java_library {
+ name: "platformprotoslite",
+ proto: {
+ type: "lite",
+ include_dirs: ["external/protobuf/src"],
+ },
+
+ srcs: [
+ ":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
+ "core/proto/**/*.proto",
+ "libs/incident/proto/android/os/**/*.proto",
+ ":service-permission-protos",
+ ],
+ exclude_srcs: [
+ "core/proto/android/privacy.proto",
+ "core/proto/android/section.proto",
+ "core/proto/android/typedef.proto",
+ ],
+ sdk_version: "core_current",
+ // Protos have lots of MissingOverride and similar.
+ errorprone: {
+ javacflags: ["-XepDisableAllChecks"],
+ },
+}
+
+// ==== c++ proto device library ==============================
+cc_defaults {
+ name: "libplatformprotos-defaults",
+
+ proto: {
+ export_proto_headers: true,
+ include_dirs: [
+ "external/protobuf/src",
+ ],
+ },
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-unused-parameter",
+ ],
+
+ srcs: [
+ ":ipconnectivity-proto-src",
+ ":libstats_atom_enum_protos",
+ "core/proto/**/*.proto",
+ ":service-permission-protos",
+ ],
+}
+
+cc_library {
+ name: "libplatformprotos",
+ defaults: ["libplatformprotos-defaults"],
+ host_supported: true,
+
+ target: {
+ host: {
+ proto: {
+ type: "full",
+ },
+ },
+ android: {
+ proto: {
+ type: "lite",
+ },
+ shared_libs: [
+ "libprotobuf-cpp-lite",
+ ],
+ shared: {
+ enabled: false,
+ },
+ },
+ },
+}
+
+// This library is meant for vendor code that needs to output protobuf. It links
+// against the static version of libprotobuf-cpp-lite, for which we can not guarantee
+// binary compatibility.
+cc_library {
+ name: "libplatformprotos-static",
+ defaults: ["libplatformprotos-defaults"],
+ host_supported: false,
+
+ // This is okay because this library is only built as a static library. The C++
+ // API is not guaranteed. The proto API is guaranteed to be stable via Metrics Council,
+ // but is not authorized to be used outside of debugging.
+ vendor_available: true,
+
+ target: {
+ android: {
+ proto: {
+ type: "lite",
+ },
+ static_libs: [
+ "libprotobuf-cpp-lite",
+ ],
+ shared: {
+ enabled: false,
+ },
+ },
+ },
+}
+
+// This is the full proto version of libplatformprotos. It may only
+// be used by test code that is not shipped on the device.
+cc_library {
+ name: "libplatformprotos-test",
+ defaults: ["libplatformprotos-defaults"],
+ host_supported: false,
+
+ target: {
+ android: {
+ proto: {
+ type: "full",
+ },
+ shared: {
+ enabled: false,
+ },
+ },
+ },
+}
diff --git a/StubLibraries.bp b/StubLibraries.bp
index a83cb4d8db3d..284e807bfc45 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -114,7 +114,7 @@ droidstubs {
last_released: {
api_file: ":android-non-updatable.api.public.latest",
removed_api_file: ":android-non-updatable-removed.api.public.latest",
- baseline_file: ":android-incompatibilities.api.public.latest",
+ baseline_file: ":android-non-updatable-incompatibilities.api.public.latest",
},
api_lint: {
enabled: true,
@@ -166,7 +166,7 @@ droidstubs {
last_released: {
api_file: ":android-non-updatable.api.system.latest",
removed_api_file: ":android-non-updatable-removed.api.system.latest",
- baseline_file: ":android-incompatibilities.api.system.latest"
+ baseline_file: ":android-non-updatable-incompatibilities.api.system.latest"
},
api_lint: {
enabled: true,
@@ -310,18 +310,67 @@ modules_system_stubs = [
]
java_defaults {
- name: "android_defaults_stubs_current",
- libs: [ "stub-annotations" ],
- static_libs: [
- // License notices from art module
- "art-notices-for-framework-stubs-jar",
- "framework-res-package-jar", // Export package of framework-res
+ name: "android-non-updatable_defaults_stubs_current",
+ libs: ["stub-annotations"],
+ static_libs: ["framework-res-package-jar"], // Export package of framework-res
+ sdk_version: "none",
+ system_modules: "none",
+ java_version: "1.8",
+ compile_dex: true,
+ dist: {
+ targets: ["sdk", "win_sdk"],
+ tag: ".jar",
+ dest: "android-non-updatable.jar",
+ }
+}
+
+java_library_static {
+ name: "android-non-updatable.stubs",
+ defaults: ["android-non-updatable_defaults_stubs_current"],
+ srcs: [":api-stubs-docs-non-updatable"],
+ libs: modules_public_stubs,
+ dist: {
+ dir: "apistubs/android/public",
+ },
+}
+
+java_library_static {
+ name: "android-non-updatable.stubs.system",
+ defaults: ["android-non-updatable_defaults_stubs_current"],
+ srcs: [ ":system-api-stubs-docs-non-updatable" ],
+ libs: modules_system_stubs,
+ dist: {
+ dir: "apistubs/android/system",
+ },
+}
+
+java_library_static {
+ name: "android-non-updatable.stubs.module_lib",
+ defaults: ["android-non-updatable_defaults_stubs_current"],
+ srcs: [":module-lib-api-stubs-docs-non-updatable"],
+ libs: [
+ "sdk_system_current_android",
+ // NOTE: The below can be removed once the prebuilt stub contains IKE.
+ "sdk_system_current_android.net.ipsec.ike",
],
- errorprone: {
- javacflags: [
- "-XepDisableAllChecks",
- ],
+ dist: {
+ dir: "apistubs/android/module-lib",
},
+}
+
+java_library_static {
+ name: "android-non-updatable.stubs.test",
+ defaults: ["android-non-updatable_defaults_stubs_current"],
+ srcs: [":test-api-stubs-docs-non-updatable"],
+ libs: modules_system_stubs,
+ dist: {
+ dir: "apistubs/android/test",
+ },
+}
+
+java_defaults {
+ name: "android_defaults_stubs_current",
+ static_libs: ["art-notices-for-framework-stubs-jar"], // License notices from art module
sdk_version: "none",
system_modules: "none",
java_version: "1.8",
@@ -339,8 +388,8 @@ java_defaults {
java_library_static {
name: "android_stubs_current",
- srcs: [ ":api-stubs-docs-non-updatable" ],
static_libs: modules_public_stubs + [
+ "android-non-updatable.stubs",
"private-stub-annotations-jar",
],
defaults: ["android_defaults_stubs_current"],
@@ -348,8 +397,8 @@ java_library_static {
java_library_static {
name: "android_system_stubs_current",
- srcs: [ ":system-api-stubs-docs-non-updatable" ],
static_libs: modules_system_stubs + [
+ "android-non-updatable.stubs.system",
"private-stub-annotations-jar",
],
defaults: [
@@ -371,10 +420,10 @@ java_library_static {
java_library_static {
name: "android_test_stubs_current",
- srcs: [ ":test-api-stubs-docs-non-updatable" ],
// Modules do not have test APIs, but we want to include their SystemApis, like we include
// the SystemApi of framework-non-updatable-sources.
static_libs: modules_system_stubs + [
+ "android-non-updatable.stubs.test",
"private-stub-annotations-jar",
],
defaults: [
@@ -396,17 +445,14 @@ java_library_static {
java_library_static {
name: "android_module_lib_stubs_current",
- srcs: [ ":module-lib-api-stubs-docs-non-updatable" ],
defaults: [
"android_defaults_stubs_current",
"android_stubs_dists_default",
],
- libs: [
- "sdk_system_current_android",
- // NOTE: The below can be removed once the prebuilt stub contains IKE.
- "sdk_system_current_android.net.ipsec.ike",
+ static_libs: [
+ "android-non-updatable.stubs.module_lib",
+ "art.module.public.api.stubs",
],
- static_libs: ["art.module.public.api.stubs"],
dist: {
dir: "apistubs/android/module-lib",
},
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
index 367748951902..ac91bdb2dce7 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
@@ -23,6 +23,7 @@ import android.app.appsearch.util.SchemaMigrationUtil;
import android.os.Bundle;
import android.os.ParcelableException;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
@@ -270,8 +271,8 @@ public final class AppSearchSession implements Closeable {
documentBundles.add(documents.get(i).getBundle());
}
try {
- // TODO(b/173532925) a timestamp needs to be sent here to calculate binder latency
mService.putDocuments(mPackageName, mDatabaseName, documentBundles, mUserId,
+ /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(),
new IAppSearchBatchResultCallback.Stub() {
public void onResult(AppSearchBatchResult result) {
executor.execute(() -> callback.onResult(result));
diff --git a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
index 4d05ad71a121..0b8f0523ab56 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
+++ b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
@@ -94,6 +94,7 @@ interface IAppSearchManager {
* @param databaseName The name of the database where this document lives.
* @param documentBundes List of GenericDocument bundles.
* @param userId Id of the calling user
+ * @param binderCallStartTimeMillis start timestamp of binder call in Millis
* @param callback
* If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError}
* will be called with the cause throwable. Otherwise,
@@ -106,6 +107,7 @@ interface IAppSearchManager {
in String databaseName,
in List<Bundle> documentBundles,
in int userId,
+ in long binderCallStartTimeMillis,
in IAppSearchBatchResultCallback callback);
/**
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
index b46e85d1d480..35c441e9eb98 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -18,6 +18,7 @@ package com.android.server.appsearch;
import static android.app.appsearch.AppSearchResult.throwableToFailedResult;
import static android.os.UserHandle.USER_NULL;
+import android.annotation.ElapsedRealtimeLong;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
@@ -45,6 +46,7 @@ import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.ParcelableException;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.ArrayMap;
@@ -57,6 +59,9 @@ import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.appsearch.external.localstorage.AppSearchImpl;
+import com.android.server.appsearch.external.localstorage.stats.CallStats;
+import com.android.server.appsearch.stats.LoggerInstanceManager;
+import com.android.server.appsearch.stats.PlatformLogger;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -80,6 +85,7 @@ public class AppSearchManagerService extends SystemService {
private PackageManagerInternal mPackageManagerInternal;
private ImplInstanceManager mImplInstanceManager;
private UserManager mUserManager;
+ private LoggerInstanceManager mLoggerInstanceManager;
// Never call shutdownNow(). It will cancel the futures it's returned. And since
// Executor#execute won't return anything, we will hang forever waiting for the execution.
@@ -106,6 +112,7 @@ public class AppSearchManagerService extends SystemService {
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
mImplInstanceManager = ImplInstanceManager.getInstance(mContext);
mUserManager = mContext.getSystemService(UserManager.class);
+ mLoggerInstanceManager = LoggerInstanceManager.getInstance();
registerReceivers();
}
@@ -147,6 +154,7 @@ public class AppSearchManagerService extends SystemService {
private void handleUserRemoved(@UserIdInt int userId) {
try {
mImplInstanceManager.removeAppSearchImplForUser(userId);
+ mLoggerInstanceManager.removePlatformLoggerForUser(userId);
Slog.i(TAG, "Removed AppSearchImpl instance for user: " + userId);
} catch (Throwable t) {
Slog.e(TAG, "Unable to remove data for user: " + userId, t);
@@ -274,6 +282,7 @@ public class AppSearchManagerService extends SystemService {
@NonNull String databaseName,
@NonNull List<Bundle> documentBundles,
@UserIdInt int userId,
+ @ElapsedRealtimeLong long binderCallStartTimeMillis,
@NonNull IAppSearchBatchResultCallback callback) {
Preconditions.checkNotNull(packageName);
Preconditions.checkNotNull(databaseName);
@@ -282,6 +291,11 @@ public class AppSearchManagerService extends SystemService {
int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid);
EXECUTOR.execute(() -> {
+ long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime();
+ @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK;
+ PlatformLogger logger = null;
+ int operationSuccessCount = 0;
+ int operationFailureCount = 0;
try {
verifyUserUnlocked(callingUserId);
verifyCallingPackage(callingUid, packageName);
@@ -289,20 +303,46 @@ public class AppSearchManagerService extends SystemService {
new AppSearchBatchResult.Builder<>();
AppSearchImpl impl =
mImplInstanceManager.getAppSearchImpl(callingUserId);
+ logger = mLoggerInstanceManager.getPlatformLogger(callingUserId);
for (int i = 0; i < documentBundles.size(); i++) {
GenericDocument document = new GenericDocument(documentBundles.get(i));
try {
- impl.putDocument(packageName, databaseName, document,
- /*logger=*/ null);
+ impl.putDocument(packageName, databaseName, document, logger);
resultBuilder.setSuccess(document.getUri(), /*result=*/ null);
+ ++operationSuccessCount;
} catch (Throwable t) {
resultBuilder.setResult(document.getUri(),
throwableToFailedResult(t));
+ AppSearchResult<Void> result = throwableToFailedResult(t);
+ resultBuilder.setResult(document.getUri(), result);
+ // for failures, we would just log the one for last failure
+ statusCode = result.getResultCode();
+ ++operationFailureCount;
}
}
invokeCallbackOnResult(callback, resultBuilder.build());
} catch (Throwable t) {
invokeCallbackOnError(callback, t);
+ } finally {
+ if (logger != null) {
+ CallStats.Builder cBuilder = new CallStats.Builder(packageName,
+ databaseName)
+ .setCallType(CallStats.CALL_TYPE_PUT_DOCUMENTS)
+ // TODO(b/173532925) check the existing binder call latency chart
+ // is good enough for us:
+ // http://dashboards/view/_72c98f9a_91d9_41d4_ab9a_bc14f79742b4
+ .setEstimatedBinderLatencyMillis(
+ 2 * (int) (totalLatencyStartTimeMillis
+ - binderCallStartTimeMillis))
+ .setNumOperationsSucceeded(operationSuccessCount)
+ .setNumOperationsFailed(operationFailureCount);
+ cBuilder.getGeneralStatsBuilder()
+ .setStatusCode(statusCode)
+ .setTotalLatencyMillis(
+ (int) (SystemClock.elapsedRealtime()
+ - totalLatencyStartTimeMillis));
+ logger.logStats(cBuilder.build());
+ }
}
});
}
@@ -717,6 +757,7 @@ public class AppSearchManagerService extends SystemService {
try {
verifyUserUnlocked(callingUserId);
mImplInstanceManager.getOrCreateAppSearchImpl(mContext, callingUserId);
+ mLoggerInstanceManager.getOrCreatePlatformLogger(getContext(), callingUserId);
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
} catch (Throwable t) {
invokeCallbackOnError(callback, t);
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
index e82dd9ad5df3..af39b790168c 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
@@ -106,7 +106,6 @@ public final class ImplInstanceManager {
*
* @param userId The multi-user userId of the user that need to be removed.
*/
- @NonNull
public void removeAppSearchImplForUser(@UserIdInt int userId) {
synchronized (mInstancesLocked) {
mInstancesLocked.remove(userId);
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/stats/LoggerInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/stats/LoggerInstanceManager.java
new file mode 100644
index 000000000000..45440633cff4
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/stats/LoggerInstanceManager.java
@@ -0,0 +1,131 @@
+/*
+ * 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.appsearch.stats;
+
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.content.Context;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.appsearch.AppSearchManagerService;
+
+/**
+ * Manages the lifecycle of instances of {@link PlatformLogger}.
+ *
+ * <p>These instances are managed per unique device-user.
+ */
+public final class LoggerInstanceManager {
+ // TODO(b/173532925) flags to control those three
+ // So probably we can't pass those three in the constructor but need to fetch the latest value
+ // every time we need them in the logger.
+ private static final int MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS = 100;
+ private static final int DEFAULT_SAMPLING_RATIO = 10;
+
+ private static volatile LoggerInstanceManager sLoggerInstanceManager;
+
+ @GuardedBy("mInstancesLocked")
+ private final SparseArray<PlatformLogger> mInstancesLocked = new SparseArray<>();
+
+ private LoggerInstanceManager() {
+ }
+
+ /**
+ * Gets an instance of {@link LoggerInstanceManager} to be used.
+ *
+ * <p>If no instance has been initialized yet, a new one will be created. Otherwise, the
+ * existing instance will be returned.
+ */
+ @NonNull
+ public static LoggerInstanceManager getInstance() {
+ if (sLoggerInstanceManager == null) {
+ synchronized (LoggerInstanceManager.class) {
+ if (sLoggerInstanceManager == null) {
+ sLoggerInstanceManager =
+ new LoggerInstanceManager();
+ }
+ }
+ }
+ return sLoggerInstanceManager;
+ }
+
+ /**
+ * Gets an instance of PlatformLogger for the given user, or creates one if none exists.
+ *
+ * @param context The context
+ * @param userId The multi-user userId of the device user calling AppSearch
+ * @return An initialized {@link PlatformLogger} for this user
+ */
+ @NonNull
+ public PlatformLogger getOrCreatePlatformLogger(
+ @NonNull Context context, @UserIdInt int userId) {
+ synchronized (mInstancesLocked) {
+ PlatformLogger instance = mInstancesLocked.get(userId);
+ if (instance == null) {
+ instance = new PlatformLogger(context, userId, new PlatformLogger.Config(
+ MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
+ DEFAULT_SAMPLING_RATIO,
+ // TODO(b/173532925) re-enable sampling ratios for different stats types
+ // once we have P/H flag manager setup in ag/13977824
+ /*samplingRatios=*/ new SparseIntArray()));
+ mInstancesLocked.put(userId, instance);
+ }
+ return instance;
+ }
+ }
+
+
+ /**
+ * Gets an instance of PlatformLogger for the given user.
+ *
+ * <p>This method should only be called by an initialized SearchSession, which has been already
+ * created the PlatformLogger instance for the given user.
+ *
+ * @param userId The multi-user userId of the device user calling AppSearch
+ * @return An initialized {@link PlatformLogger} for this user
+ * @throws IllegalStateException if {@link PlatformLogger} haven't created for the given user.
+ */
+ @NonNull
+ public PlatformLogger getPlatformLogger(@UserIdInt int userId) {
+ synchronized (mInstancesLocked) {
+ PlatformLogger instance = mInstancesLocked.get(userId);
+ if (instance == null) {
+ // Impossible scenario, user cannot call an uninitialized SearchSession,
+ // getInstance should always find the instance for the given user and never try to
+ // create an instance for this user again.
+ throw new IllegalStateException(
+ "PlatformLogger has never been created for this user: " + userId);
+ }
+ return instance;
+ }
+ }
+
+ /**
+ * Remove an instance of {@link PlatformLogger} for the given user.
+ *
+ * <p>This method should only be called if {@link AppSearchManagerService} receives an
+ * ACTION_USER_REMOVED, which the logger instance of given user should be removed.
+ *
+ * @param userId The multi-user userId of the user that need to be removed.
+ */
+ public void removePlatformLoggerForUser(@UserIdInt int userId) {
+ synchronized (mInstancesLocked) {
+ mInstancesLocked.remove(userId);
+ }
+ }
+}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java b/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
index aeb66d90b5be..1c04d99ac2c7 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
@@ -17,21 +17,26 @@
package com.android.server.appsearch.stats;
import android.annotation.NonNull;
-import android.annotation.Nullable;
+import android.app.appsearch.exceptions.AppSearchException;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Process;
import android.os.SystemClock;
import android.util.ArrayMap;
+import android.util.Log;
import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.Preconditions;
import com.android.server.appsearch.external.localstorage.AppSearchLogger;
import com.android.server.appsearch.external.localstorage.stats.CallStats;
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.Random;
@@ -120,19 +125,18 @@ public final class PlatformLogger implements AppSearchLogger {
* @param minTimeIntervalBetweenSamplesMillis minimum time interval apart in Milliseconds
* required for two consecutive stats logged
* @param defaultSamplingRatio default sampling ratio
- * @param samplingRatios SparseArray to customize sampling ratio for
+ * @param samplingRatios SparseArray to customize sampling ratio for
* different stat types
*/
public Config(long minTimeIntervalBetweenSamplesMillis,
int defaultSamplingRatio,
- @Nullable SparseIntArray samplingRatios) {
+ @NonNull SparseIntArray samplingRatios) {
+ // TODO(b/173532925) Probably we can get rid of those three after we have p/h flags
+ // for them.
+ // e.g. we can just call DeviceConfig.get(SAMPLING_RATIO_FOR_PUT_DOCUMENTS).
mMinTimeIntervalBetweenSamplesMillis = minTimeIntervalBetweenSamplesMillis;
mDefaultSamplingRatio = defaultSamplingRatio;
- if (samplingRatios != null) {
- mSamplingRatios = samplingRatios;
- } else {
- mSamplingRatios = new SparseIntArray();
- }
+ mSamplingRatios = samplingRatios;
}
}
@@ -169,7 +173,7 @@ public final class PlatformLogger implements AppSearchLogger {
Preconditions.checkNotNull(stats);
synchronized (mLock) {
if (shouldLogForTypeLocked(stats.getCallType())) {
- logToWestworldLocked(stats);
+ logStatsImplLocked(stats);
}
}
}
@@ -180,7 +184,7 @@ public final class PlatformLogger implements AppSearchLogger {
Preconditions.checkNotNull(stats);
synchronized (mLock) {
if (shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)) {
- logToWestworldLocked(stats);
+ logStatsImplLocked(stats);
}
}
}
@@ -201,25 +205,103 @@ public final class PlatformLogger implements AppSearchLogger {
}
@GuardedBy("mLock")
- private void logToWestworldLocked(@NonNull CallStats stats) {
+ private void logStatsImplLocked(@NonNull CallStats stats) {
mLastPushTimeMillisLocked = SystemClock.elapsedRealtime();
ExtraStats extraStats = createExtraStatsLocked(stats.getGeneralStats().getPackageName(),
stats.getCallType());
- /* TODO(b/173532925) Log the CallStats to Westworld
- stats.log(..., samplingRatio, skippedSampleCount, ...)
- */
+ String database = stats.getGeneralStats().getDatabase();
+ try {
+ int hashCodeForDatabase = calculateHashCodeMd5(database);
+ FrameworkStatsLog.write(FrameworkStatsLog.APP_SEARCH_CALL_STATS_REPORTED,
+ extraStats.mSamplingRatio,
+ extraStats.mSkippedSampleCount,
+ extraStats.mPackageUid,
+ hashCodeForDatabase,
+ stats.getGeneralStats().getStatusCode(),
+ stats.getGeneralStats().getTotalLatencyMillis(),
+ stats.getCallType(),
+ stats.getEstimatedBinderLatencyMillis(),
+ stats.getNumOperationsSucceeded(),
+ stats.getNumOperationsFailed());
+ } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
+ // TODO(b/184204720) report hashing error to Westworld
+ // We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database,
+ // so in the dashboard we know there is some error for hashing.
+ //
+ // Something is wrong while calculating the hash code for database
+ // this shouldn't happen since we always use "MD5" and "UTF-8"
+ Log.e(TAG, "Error calculating hash code for database " + database, e);
+ }
}
@GuardedBy("mLock")
- private void logToWestworldLocked(@NonNull PutDocumentStats stats) {
+ private void logStatsImplLocked(@NonNull PutDocumentStats stats) {
mLastPushTimeMillisLocked = SystemClock.elapsedRealtime();
ExtraStats extraStats = createExtraStatsLocked(stats.getGeneralStats().getPackageName(),
CallStats.CALL_TYPE_PUT_DOCUMENT);
- /* TODO(b/173532925) Log the PutDocumentStats to Westworld
- stats.log(..., samplingRatio, skippedSampleCount, ...)
- */
+ String database = stats.getGeneralStats().getDatabase();
+ try {
+ int hashCodeForDatabase = calculateHashCodeMd5(database);
+ FrameworkStatsLog.write(FrameworkStatsLog.APP_SEARCH_PUT_DOCUMENT_STATS_REPORTED,
+ extraStats.mSamplingRatio,
+ extraStats.mSkippedSampleCount,
+ extraStats.mPackageUid,
+ hashCodeForDatabase,
+ stats.getGeneralStats().getStatusCode(),
+ stats.getGeneralStats().getTotalLatencyMillis(),
+ stats.getGenerateDocumentProtoLatencyMillis(),
+ stats.getRewriteDocumentTypesLatencyMillis(),
+ stats.getNativeLatencyMillis(),
+ stats.getNativeDocumentStoreLatencyMillis(),
+ stats.getNativeIndexLatencyMillis(),
+ stats.getNativeIndexMergeLatencyMillis(),
+ stats.getNativeDocumentSizeBytes(),
+ stats.getNativeNumTokensIndexed(),
+ stats.getNativeExceededMaxNumTokens());
+ } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
+ // TODO(b/184204720) report hashing error to Westworld
+ // We need to set a special value(e.g. 0xFFFFFFFF) for the hashing of the database,
+ // so in the dashboard we know there is some error for hashing.
+ //
+ // Something is wrong while calculating the hash code for database
+ // this shouldn't happen since we always use "MD5" and "UTF-8"
+ Log.e(TAG, "Error calculating hash code for database " + database, e);
+ }
}
+ /**
+ * Calculate the hash code as an integer by returning the last four bytes of its MD5.
+ *
+ * @param str a string
+ * @return hash code as an integer
+ * @throws AppSearchException if either algorithm or encoding does not exist.
+ */
+ @VisibleForTesting
+ @NonNull
+ static int calculateHashCodeMd5(@NonNull String str) throws
+ NoSuchAlgorithmException, UnsupportedEncodingException {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ md.update(str.getBytes(/*charsetName=*/ "UTF-8"));
+ byte[] digest = md.digest();
+
+ // Since MD5 generates 16 bytes digest, we don't need to check the length here to see
+ // if it is smaller than sizeof(int)(4).
+ //
+ // We generate the same value as BigInteger(digest).intValue().
+ // BigInteger takes bytes[] and treat it as big endian. And its intValue() would get the
+ // lower 4 bytes. So here we take the last 4 bytes and treat them as big endian.
+ return (digest[12] & 0xFF) << 24
+ | (digest[13] & 0xFF) << 16
+ | (digest[14] & 0xFF) << 8
+ | (digest[15] & 0xFF);
+ }
+
+ /**
+ * Creates {@link ExtraStats} to hold additional information generated for logging.
+ *
+ * <p>This method is called by most of logToWestworldLocked functions to reduce code
+ * duplication.
+ */
@VisibleForTesting
@GuardedBy("mLock")
@NonNull
diff --git a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
index d459c0502189..44e87c370fc1 100644
--- a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
+++ b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
@@ -176,8 +176,6 @@ public class PowerExemptionManager {
/** @hide */
public static final int REASON_DEVICE_DEMO_MODE = 63;
/** @hide */
- public static final int REASON_EXEMPTED_PACKAGE = 64;
- /** @hide */
public static final int REASON_ALLOWLISTED_PACKAGE = 65;
/** @hide */
public static final int REASON_APPOP = 66;
@@ -344,7 +342,6 @@ public class PowerExemptionManager {
REASON_INSTR_BACKGROUND_FGS_PERMISSION,
REASON_SYSTEM_ALERT_WINDOW_PERMISSION,
REASON_DEVICE_DEMO_MODE,
- REASON_EXEMPTED_PACKAGE,
REASON_ALLOWLISTED_PACKAGE,
REASON_APPOP,
REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD,
@@ -601,8 +598,6 @@ public class PowerExemptionManager {
return "SYSTEM_ALERT_WINDOW_PERMISSION";
case REASON_DEVICE_DEMO_MODE:
return "DEVICE_DEMO_MODE";
- case REASON_EXEMPTED_PACKAGE:
- return "EXEMPTED_PACKAGE";
case REASON_ALLOWLISTED_PACKAGE:
return "ALLOWLISTED_PACKAGE";
case REASON_APPOP:
diff --git a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
index 07231b099815..29a5dee0be26 100644
--- a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
+++ b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
@@ -176,8 +176,6 @@ public class PowerWhitelistManager {
/** @hide */
public static final int REASON_DEVICE_DEMO_MODE = PowerExemptionManager.REASON_DEVICE_DEMO_MODE;
/** @hide */
- public static final int REASON_EXEMPTED_PACKAGE = PowerExemptionManager.REASON_EXEMPTED_PACKAGE;
- /** @hide */
public static final int REASON_ALLOWLISTED_PACKAGE =
PowerExemptionManager.REASON_ALLOWLISTED_PACKAGE;
/** @hide */
@@ -341,7 +339,6 @@ public class PowerWhitelistManager {
REASON_INSTR_BACKGROUND_FGS_PERMISSION,
REASON_SYSTEM_ALERT_WINDOW_PERMISSION,
REASON_DEVICE_DEMO_MODE,
- REASON_EXEMPTED_PACKAGE,
REASON_ALLOWLISTED_PACKAGE,
REASON_APPOP,
// temp and system allowlist reasons.
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index d17df63c4363..97ee0e131ef2 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -49,6 +49,7 @@ import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_NEVER;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RESTRICTED;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static com.android.server.SystemService.PHASE_BOOT_COMPLETED;
import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
@@ -1207,6 +1208,11 @@ public class AppStandbyController
return STANDBY_BUCKET_ACTIVE;
}
+ if (mPackageManager.checkPermission(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION,
+ packageName) == PERMISSION_GRANTED) {
+ return STANDBY_BUCKET_FREQUENT;
+ }
+
return STANDBY_BUCKET_NEVER;
}
diff --git a/apex/media/framework/lint-baseline.xml b/apex/media/framework/lint-baseline.xml
new file mode 100644
index 000000000000..e1b145083f80
--- /dev/null
+++ b/apex/media/framework/lint-baseline.xml
@@ -0,0 +1,312 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 29): `new android.media.ApplicationMediaCapabilities.Builder`"
+ errorLine1=" new ApplicationMediaCapabilities.Builder();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java"
+ line="208"
+ column="29"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 29): `new android.media.ApplicationMediaCapabilities.Builder`"
+ errorLine1=" ApplicationMediaCapabilities.Builder builder = new ApplicationMediaCapabilities.Builder();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java"
+ line="314"
+ column="56"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.os.RemoteException#rethrowFromSystemServer`"
+ errorLine1=" e.rethrowFromSystemServer();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaCommunicationManager.java"
+ line="110"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.os.Parcel#writeParcelableCreator`"
+ errorLine1=" dest.writeParcelableCreator((Parcelable) parcelable);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParceledListSlice.java"
+ line="77"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.os.Parcel#readParcelableCreator`"
+ errorLine1=" return from.readParcelableCreator(loader);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParceledListSlice.java"
+ line="82"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.MediaParser.TrackData#mediaFormat`"
+ errorLine1=" this.mediaFormat = mediaFormat;"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="273"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.MediaParser.TrackData#drmInitData`"
+ errorLine1=" this.drmInitData = drmInitData;"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="274"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
+ errorLine1=" this.timeMicros = timeMicros;"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="295"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
+ errorLine1=" this.position = position;"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="296"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
+ errorLine1=" return &quot;[timeMicros=&quot; + timeMicros + &quot;, position=&quot; + position + &quot;]&quot;;"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="302"
+ column="66"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
+ errorLine1=" return &quot;[timeMicros=&quot; + timeMicros + &quot;, position=&quot; + position + &quot;]&quot;;"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="302"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level R (current min is 29): `android.media.MediaParser.SeekPoint`"
+ errorLine1=" SeekPoint other = (SeekPoint) obj;"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="313"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
+ errorLine1=" return timeMicros == other.timeMicros &amp;&amp; position == other.position;"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="314"
+ column="54"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
+ errorLine1=" return timeMicros == other.timeMicros &amp;&amp; position == other.position;"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="314"
+ column="66"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
+ errorLine1=" return timeMicros == other.timeMicros &amp;&amp; position == other.position;"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="314"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
+ errorLine1=" return timeMicros == other.timeMicros &amp;&amp; position == other.position;"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="314"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
+ errorLine1=" int result = (int) timeMicros;"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="319"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
+ errorLine1=" result = 31 * result + (int) position;"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="320"
+ column="42"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level R (current min is 29): `android.media.MediaParser.InputReader`"
+ errorLine1=" public interface SeekableInputReader extends InputReader {"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="352"
+ column="50"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 31 (current min is 29): `android.media.metrics.LogSessionId#LOG_SESSION_ID_NONE`"
+ errorLine1=" @NonNull private LogSessionId mLogSessionId = LogSessionId.LOG_SESSION_ID_NONE;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="1071"
+ column="51"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast from `SeekableInputReader` to `InputReader` requires API level 30 (current min is 29)"
+ errorLine1=" mExoDataReader.mInputReader = seekableInputReader;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="1201"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
+ errorLine1=" mPendingSeekPosition = seekPoint.position;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="1287"
+ column="36"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
+ errorLine1=" mPendingSeekTimeMicros = seekPoint.timeMicros;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="1288"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
+ errorLine1=" mExtractor.seek(seekPoint.position, seekPoint.timeMicros);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="1290"
+ column="29"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
+ errorLine1=" mExtractor.seek(seekPoint.position, seekPoint.timeMicros);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="1290"
+ column="49"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level R (current min is 29): `android.media.DrmInitData.SchemeInitData#uuid`"
+ errorLine1=" if (schemeInitData.uuid.equals(schemeUuid)) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="1579"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level R (current min is 29): `android.media.MediaParser.InputReader`"
+ errorLine1=" private static final class DataReaderAdapter implements InputReader {"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="1872"
+ column="61"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level R (current min is 29): `android.media.MediaParser.InputReader`"
+ errorLine1=" private static final class ParsableByteArrayAdapter implements InputReader {"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+ line="1905"
+ column="68"/>
+ </issue>
+
+</issues>
diff --git a/api/Android.bp b/api/Android.bp
index 4baf7c1d5836..65712704f358 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -336,6 +336,9 @@ genrule {
genrule {
name: "combined-removed-dex",
+ visibility: [
+ "//frameworks/base/boot",
+ ],
srcs: [
":frameworks-base-api-removed.txt",
":frameworks-base-api-system-removed.txt",
diff --git a/boot/Android.bp b/boot/Android.bp
index 71edea27ada6..844dd64ce8d7 100644
--- a/boot/Android.bp
+++ b/boot/Android.bp
@@ -43,4 +43,49 @@ package {
// done correctly.
platform_bootclasspath {
name: "platform-bootclasspath",
+
+ // Additional information needed by hidden api processing.
+ hidden_api: {
+ unsupported: [
+ "hiddenapi/hiddenapi-unsupported.txt",
+ ],
+ removed: [
+ ":combined-removed-dex",
+ ],
+ max_target_r_low_priority: [
+ "hiddenapi/hiddenapi-max-target-r-loprio.txt",
+ ],
+ max_target_q: [
+ "hiddenapi/hiddenapi-max-target-q.txt",
+ ],
+ max_target_p: [
+ "hiddenapi/hiddenapi-max-target-p.txt",
+ ],
+ max_target_o_low_priority: [
+ "hiddenapi/hiddenapi-max-target-o.txt",
+ ],
+ blocked: [
+ "hiddenapi/hiddenapi-force-blocked.txt",
+ ],
+ unsupported_packages: [
+ "hiddenapi/hiddenapi-unsupported-packages.txt",
+ ],
+ },
+
+ dists: [
+ {
+ targets: ["droidcore"],
+ tag: "hiddenapi-flags.csv",
+ },
+ {
+ targets: ["droidcore"],
+ tag: "hiddenapi-index.csv",
+ },
+ {
+ targets: ["droidcore"],
+ tag: "hiddenapi-metadata.csv",
+ // Legacy name
+ dest: "hiddenapi-unsupported.csv",
+ },
+ ],
}
diff --git a/core/api/current.txt b/core/api/current.txt
index 1f7da095a1a7..acf4350534f5 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -3960,6 +3960,7 @@ package android.app {
method public boolean isImmersive();
method public boolean isInMultiWindowMode();
method public boolean isInPictureInPictureMode();
+ method public boolean isLaunchedFromBubble();
method public boolean isLocalVoiceInteractionSupported();
method public boolean isTaskRoot();
method public boolean isVoiceInteraction();
@@ -7202,7 +7203,6 @@ package android.app.admin {
method public boolean isComplianceAcknowledgementRequired();
method public boolean isDeviceIdAttestationSupported();
method public boolean isDeviceOwnerApp(String);
- method public boolean isEnterpriseNetworkPreferenceEnabled();
method public boolean isEphemeralUser(@NonNull android.content.ComponentName);
method public boolean isKeyPairGrantedToWifiAuth(@NonNull String);
method public boolean isLockTaskPermitted(String);
@@ -7213,6 +7213,7 @@ package android.app.admin {
method public boolean isOrganizationOwnedDeviceWithManagedProfile();
method public boolean isOverrideApnEnabled(@NonNull android.content.ComponentName);
method public boolean isPackageSuspended(@NonNull android.content.ComponentName, String) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public boolean isPreferentialNetworkServiceEnabled();
method public boolean isProfileOwnerApp(String);
method public boolean isProvisioningAllowed(@NonNull String);
method public boolean isResetPasswordTokenActive(android.content.ComponentName);
@@ -7264,7 +7265,6 @@ package android.app.admin {
method public void setDelegatedScopes(@NonNull android.content.ComponentName, @NonNull String, @NonNull java.util.List<java.lang.String>);
method public void setDeviceOwnerLockScreenInfo(@NonNull android.content.ComponentName, CharSequence);
method public void setEndUserSessionMessage(@NonNull android.content.ComponentName, @Nullable CharSequence);
- method public void setEnterpriseNetworkPreferenceEnabled(boolean);
method public void setFactoryResetProtectionPolicy(@NonNull android.content.ComponentName, @Nullable android.app.admin.FactoryResetProtectionPolicy);
method public int setGlobalPrivateDnsModeOpportunistic(@NonNull android.content.ComponentName);
method @WorkerThread public int setGlobalPrivateDnsModeSpecifiedHost(@NonNull android.content.ComponentName, @NonNull String);
@@ -7307,6 +7307,7 @@ package android.app.admin {
method public boolean setPermittedCrossProfileNotificationListeners(@NonNull android.content.ComponentName, @Nullable java.util.List<java.lang.String>);
method public boolean setPermittedInputMethods(@NonNull android.content.ComponentName, java.util.List<java.lang.String>);
method public void setPersonalAppsSuspended(@NonNull android.content.ComponentName, boolean);
+ method public void setPreferentialNetworkServiceEnabled(boolean);
method public void setProfileEnabled(@NonNull android.content.ComponentName);
method public void setProfileName(@NonNull android.content.ComponentName, String);
method public void setRecommendedGlobalProxy(@NonNull android.content.ComponentName, @Nullable android.net.ProxyInfo);
@@ -7399,7 +7400,7 @@ package android.app.admin {
field public static final String EXTRA_PROVISIONING_LOGO_URI = "android.app.extra.PROVISIONING_LOGO_URI";
field @Deprecated public static final String EXTRA_PROVISIONING_MAIN_COLOR = "android.app.extra.PROVISIONING_MAIN_COLOR";
field public static final String EXTRA_PROVISIONING_MODE = "android.app.extra.PROVISIONING_MODE";
- field public static final String EXTRA_PROVISIONING_PERMISSION_GRANT_OPT_OUT = "android.app.extra.PROVISIONING_PERMISSION_GRANT_OPT_OUT";
+ field public static final String EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT = "android.app.extra.PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT";
field public static final String EXTRA_PROVISIONING_SERIAL_NUMBER = "android.app.extra.PROVISIONING_SERIAL_NUMBER";
field public static final String EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS = "android.app.extra.PROVISIONING_SKIP_EDUCATION_SCREENS";
field public static final String EXTRA_PROVISIONING_SKIP_ENCRYPTION = "android.app.extra.PROVISIONING_SKIP_ENCRYPTION";
@@ -10644,6 +10645,7 @@ package android.content {
field public static final String NOTIFICATION_SERVICE = "notification";
field public static final String NSD_SERVICE = "servicediscovery";
field public static final String PEOPLE_SERVICE = "people";
+ field public static final String PERFORMANCE_HINT_SERVICE = "performance_hint";
field public static final String POWER_SERVICE = "power";
field public static final String PRINT_SERVICE = "print";
field public static final int RECEIVER_VISIBLE_TO_INSTANT_APPS = 1; // 0x1
@@ -10667,7 +10669,7 @@ package android.content {
field public static final String USB_SERVICE = "usb";
field public static final String USER_SERVICE = "user";
field public static final String VIBRATOR_MANAGER_SERVICE = "vibrator_manager";
- field public static final String VIBRATOR_SERVICE = "vibrator";
+ field @Deprecated public static final String VIBRATOR_SERVICE = "vibrator";
field public static final String VPN_MANAGEMENT_SERVICE = "vpn_management";
field @UiContext public static final String WALLPAPER_SERVICE = "wallpaper";
field public static final String WIFI_AWARE_SERVICE = "wifiaware";
@@ -11221,7 +11223,6 @@ package android.content {
field public static final String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
field public static final String EXTRA_INSTALLER_PACKAGE_NAME = "android.intent.extra.INSTALLER_PACKAGE_NAME";
field public static final String EXTRA_INTENT = "android.intent.extra.INTENT";
- field public static final String EXTRA_IS_BUBBLED = "android.intent.extra.IS_BUBBLED";
field public static final String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT";
field public static final String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY";
field public static final String EXTRA_LOCUS_ID = "android.intent.extra.LOCUS_ID";
@@ -12085,7 +12086,6 @@ package android.content.pm {
}
public class DataLoaderParams {
- method @NonNull public static final android.content.pm.DataLoaderParams forIncremental(@NonNull android.content.ComponentName, @NonNull String);
method @NonNull public static final android.content.pm.DataLoaderParams forStreaming(@NonNull android.content.ComponentName, @NonNull String);
method @NonNull public final String getArguments();
method @NonNull public final android.content.ComponentName getComponentName();
@@ -12330,7 +12330,6 @@ package android.content.pm {
field public static final String ACTION_SESSION_COMMITTED = "android.content.pm.action.SESSION_COMMITTED";
field public static final String ACTION_SESSION_DETAILS = "android.content.pm.action.SESSION_DETAILS";
field public static final String ACTION_SESSION_UPDATED = "android.content.pm.action.SESSION_UPDATED";
- field public static final int DATA_LOADER_TYPE_INCREMENTAL = 2; // 0x2
field public static final int DATA_LOADER_TYPE_NONE = 0; // 0x0
field public static final int DATA_LOADER_TYPE_STREAMING = 1; // 0x1
field public static final String EXTRA_DATA_LOADER_TYPE = "android.content.pm.extra.DATA_LOADER_TYPE";
@@ -12732,7 +12731,6 @@ package android.content.pm {
field public static final String FEATURE_TOUCHSCREEN_MULTITOUCH = "android.hardware.touchscreen.multitouch";
field public static final String FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT = "android.hardware.touchscreen.multitouch.distinct";
field public static final String FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND = "android.hardware.touchscreen.multitouch.jazzhand";
- field public static final String FEATURE_TRANSLATION = "android.software.translation";
field public static final String FEATURE_USB_ACCESSORY = "android.hardware.usb.accessory";
field public static final String FEATURE_USB_HOST = "android.hardware.usb.host";
field public static final String FEATURE_VERIFIED_BOOT = "android.software.verified_boot";
@@ -20235,6 +20233,7 @@ package android.media {
field public static final int TYPE_FM_TUNER = 16; // 0x10
field public static final int TYPE_HDMI = 9; // 0x9
field public static final int TYPE_HDMI_ARC = 10; // 0xa
+ field public static final int TYPE_HDMI_EARC = 29; // 0x1d
field public static final int TYPE_HEARING_AID = 23; // 0x17
field public static final int TYPE_IP = 20; // 0x14
field public static final int TYPE_LINE_ANALOG = 5; // 0x5
@@ -30835,16 +30834,16 @@ package android.os {
method public void onCancel();
}
- public abstract class CombinedVibrationEffect implements android.os.Parcelable {
- method @NonNull public static android.os.CombinedVibrationEffect createSynced(@NonNull android.os.VibrationEffect);
+ public abstract class CombinedVibration implements android.os.Parcelable {
+ method @NonNull public static android.os.CombinedVibration createParallel(@NonNull android.os.VibrationEffect);
method public int describeContents();
- method @NonNull public static android.os.CombinedVibrationEffect.SyncedCombination startSynced();
- field @NonNull public static final android.os.Parcelable.Creator<android.os.CombinedVibrationEffect> CREATOR;
+ method @NonNull public static android.os.CombinedVibration.ParallelCombination startParallel();
+ field @NonNull public static final android.os.Parcelable.Creator<android.os.CombinedVibration> CREATOR;
}
- public static final class CombinedVibrationEffect.SyncedCombination {
- method @NonNull public android.os.CombinedVibrationEffect.SyncedCombination addVibrator(int, @NonNull android.os.VibrationEffect);
- method @NonNull public android.os.CombinedVibrationEffect combine();
+ public static final class CombinedVibration.ParallelCombination {
+ method @NonNull public android.os.CombinedVibration.ParallelCombination addVibrator(int, @NonNull android.os.VibrationEffect);
+ method @NonNull public android.os.CombinedVibration combine();
}
public class ConditionVariable {
@@ -31559,6 +31558,17 @@ package android.os {
field public static final int PATTERN_SUFFIX = 4; // 0x4
}
+ public final class PerformanceHintManager {
+ method @Nullable public android.os.PerformanceHintManager.Session createHintSession(@NonNull int[], long);
+ method public long getPreferredUpdateRateNanos();
+ }
+
+ public static class PerformanceHintManager.Session implements java.io.Closeable {
+ method public void close();
+ method public void reportActualWorkDuration(long);
+ method public void updateTargetWorkDuration(long);
+ }
+
public final class PersistableBundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
ctor public PersistableBundle();
ctor public PersistableBundle(int);
@@ -32086,8 +32096,8 @@ package android.os {
method @NonNull public abstract android.os.Vibrator getDefaultVibrator();
method @NonNull public abstract android.os.Vibrator getVibrator(int);
method @NonNull public abstract int[] getVibratorIds();
- method @RequiresPermission(android.Manifest.permission.VIBRATE) public final void vibrate(@NonNull android.os.CombinedVibrationEffect);
- method @RequiresPermission(android.Manifest.permission.VIBRATE) public final void vibrate(@NonNull android.os.CombinedVibrationEffect, @Nullable android.os.VibrationAttributes);
+ method @RequiresPermission(android.Manifest.permission.VIBRATE) public final void vibrate(@NonNull android.os.CombinedVibration);
+ method @RequiresPermission(android.Manifest.permission.VIBRATE) public final void vibrate(@NonNull android.os.CombinedVibration, @Nullable android.os.VibrationAttributes);
}
public class WorkSource implements android.os.Parcelable {
@@ -47127,7 +47137,7 @@ package android.view {
method @NonNull public android.hardware.SensorManager getSensorManager();
method public int getSources();
method public int getVendorId();
- method public android.os.Vibrator getVibrator();
+ method @Deprecated public android.os.Vibrator getVibrator();
method @NonNull public android.os.VibratorManager getVibratorManager();
method public boolean[] hasKeys(int...);
method public boolean hasMicrophone();
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index cdbb292a74b3..b1e448b7dd77 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -56,7 +56,7 @@ package android.app.usage {
package android.content {
public abstract class ContentProvider implements android.content.ComponentCallbacks2 {
- method @NonNull public static android.net.Uri createContentUriAsUser(@NonNull android.net.Uri, @NonNull android.os.UserHandle);
+ method @NonNull public static android.net.Uri createContentUriForUser(@NonNull android.net.Uri, @NonNull android.os.UserHandle);
}
public abstract class Context {
@@ -260,7 +260,7 @@ package android.os {
}
public static class Build.VERSION {
- field public static final int FIRST_SDK_INT;
+ field public static final int DEVICE_INITIAL_SDK_INT;
}
public interface Parcelable {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 52427821a912..d42f07d6b070 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -2230,7 +2230,7 @@ package android.bluetooth.le {
package android.companion {
public final class CompanionDeviceManager {
- method @RequiresPermission(android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES) public boolean associate(@NonNull String, @NonNull android.net.MacAddress);
+ method @RequiresPermission(android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES) public void associate(@NonNull String, @NonNull android.net.MacAddress);
method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean canPairWithoutPrompt(@NonNull String, @NonNull String, int);
method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean isDeviceAssociatedForWifiConnection(@NonNull String, @NonNull android.net.MacAddress, @NonNull android.os.UserHandle);
}
@@ -2523,6 +2523,10 @@ package android.content.pm {
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_PROFILES) public void startActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle);
}
+ public class DataLoaderParams {
+ method @NonNull public static final android.content.pm.DataLoaderParams forIncremental(@NonNull android.content.ComponentName, @NonNull String);
+ }
+
public final class InstantAppInfo implements android.os.Parcelable {
ctor public InstantAppInfo(android.content.pm.ApplicationInfo, String[], String[]);
ctor public InstantAppInfo(String, CharSequence, String[], String[]);
@@ -2613,6 +2617,7 @@ package android.content.pm {
public class PackageInstaller {
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean);
+ field public static final int DATA_LOADER_TYPE_INCREMENTAL = 2; // 0x2
}
public static class PackageInstaller.Session implements java.io.Closeable {
@@ -8020,14 +8025,14 @@ package android.os {
method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.os.connectivity.WifiBatteryStats getWifiBatteryStats();
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportFullWifiLockAcquiredFromSource(@NonNull android.os.WorkSource);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportFullWifiLockReleasedFromSource(@NonNull android.os.WorkSource);
- method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportMobileRadioPowerState(boolean, int) throws java.lang.RuntimeException;
+ method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportMobileRadioPowerState(boolean, int);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiBatchedScanStartedFromSource(@NonNull android.os.WorkSource, @IntRange(from=0) int);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiBatchedScanStoppedFromSource(@NonNull android.os.WorkSource);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiMulticastDisabled(@NonNull android.os.WorkSource);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiMulticastEnabled(@NonNull android.os.WorkSource);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiOff();
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiOn();
- method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiRadioPowerState(boolean, int) throws java.lang.RuntimeException;
+ method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiRadioPowerState(boolean, int);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiRssiChanged(@IntRange(from=0xffffff81, to=0) int);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiScanStartedFromSource(@NonNull android.os.WorkSource);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiScanStoppedFromSource(@NonNull android.os.WorkSource);
@@ -8558,7 +8563,7 @@ package android.os {
method @NonNull public static String formatUid(int);
method public static int getAppId(int);
method public int getIdentifier();
- method public static int getUid(@NonNull android.os.UserHandle, int);
+ method public int getUid(int);
method @Deprecated public boolean isOwner();
method public boolean isSystem();
method public static int myUserId();
@@ -9296,6 +9301,7 @@ package android.provider {
field public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS = "lock_screen_show_notifications";
field public static final String ODI_CAPTIONS_ENABLED = "odi_captions_enabled";
field public static final String THEME_CUSTOMIZATION_OVERLAY_PACKAGES = "theme_customization_overlay_packages";
+ field public static final String UI_TRANSLATION_ENABLED = "ui_translation_enabled";
field public static final String USER_SETUP_COMPLETE = "user_setup_complete";
field public static final int USER_SETUP_PERSONALIZATION_COMPLETE = 10; // 0xa
field public static final int USER_SETUP_PERSONALIZATION_NOT_STARTED = 0; // 0x0
@@ -9816,7 +9822,6 @@ package android.service.displayhash {
public final class DisplayHashParams implements android.os.Parcelable {
method public int describeContents();
method @Nullable public android.util.Size getBufferSize();
- method public boolean isBufferScaleWithFiltering();
method public boolean isGrayscaleBuffer();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.service.displayhash.DisplayHashParams> CREATOR;
@@ -9825,7 +9830,6 @@ package android.service.displayhash {
public static final class DisplayHashParams.Builder {
ctor public DisplayHashParams.Builder();
method @NonNull public android.service.displayhash.DisplayHashParams build();
- method @NonNull public android.service.displayhash.DisplayHashParams.Builder setBufferScaleWithFiltering(boolean);
method @NonNull public android.service.displayhash.DisplayHashParams.Builder setBufferSize(int, int);
method @NonNull public android.service.displayhash.DisplayHashParams.Builder setGrayscaleBuffer(boolean);
}
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 63e90100b6b4..a38f9f4768d3 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -137,6 +137,7 @@ package android.app {
method public void setLaunchActivityType(int);
method public void setLaunchTaskId(int);
method public void setLaunchWindowingMode(int);
+ method public void setLaunchedFromBubble(boolean);
method public void setTaskAlwaysOnTop(boolean);
method public void setTaskOverlay(boolean, boolean);
}
@@ -156,10 +157,7 @@ package android.app {
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void moveTaskToRootTask(int, int, boolean);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void removeRootTasksInWindowingModes(@NonNull int[]);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void removeRootTasksWithActivityTypes(@NonNull int[]);
- method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void resizePrimarySplitScreen(@NonNull android.graphics.Rect, @NonNull android.graphics.Rect);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void resizeTask(int, android.graphics.Rect);
- method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public boolean setTaskWindowingMode(int, int, boolean) throws java.lang.SecurityException;
- method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public boolean setTaskWindowingModeSplitScreenPrimary(int, boolean);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void startSystemLockTaskMode(int);
method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) public void stopSystemLockTaskMode();
method public static boolean supportsMultiWindow(android.content.Context);
@@ -1378,6 +1376,11 @@ package android.media {
method public static int xsdStringToUsage(@NonNull String);
}
+ public final class AudioDeviceInfo {
+ method public static void enforceValidAudioDeviceTypeIn(int);
+ method public static void enforceValidAudioDeviceTypeOut(int);
+ }
+
public final class AudioFocusRequest {
method @Nullable public android.media.AudioManager.OnAudioFocusChangeListener getOnAudioFocusChangeListener();
}
@@ -1592,43 +1595,43 @@ package android.os {
public static class Build.VERSION {
field public static final String[] ACTIVE_CODENAMES;
- field public static final int FIRST_SDK_INT;
+ field public static final int DEVICE_INITIAL_SDK_INT;
field public static final int RESOURCES_SDK_INT;
}
- public abstract class CombinedVibrationEffect implements android.os.Parcelable {
+ public abstract class CombinedVibration implements android.os.Parcelable {
method public abstract long getDuration();
- method @NonNull public static android.os.CombinedVibrationEffect.SequentialCombination startSequential();
+ method @NonNull public static android.os.CombinedVibration.SequentialCombination startSequential();
}
- public static final class CombinedVibrationEffect.Mono extends android.os.CombinedVibrationEffect {
+ public static final class CombinedVibration.Mono extends android.os.CombinedVibration {
method public long getDuration();
method @NonNull public android.os.VibrationEffect getEffect();
method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.os.CombinedVibrationEffect.Mono> CREATOR;
+ field @NonNull public static final android.os.Parcelable.Creator<android.os.CombinedVibration.Mono> CREATOR;
}
- public static final class CombinedVibrationEffect.Sequential extends android.os.CombinedVibrationEffect {
+ public static final class CombinedVibration.Sequential extends android.os.CombinedVibration {
method @NonNull public java.util.List<java.lang.Integer> getDelays();
method public long getDuration();
- method @NonNull public java.util.List<android.os.CombinedVibrationEffect> getEffects();
+ method @NonNull public java.util.List<android.os.CombinedVibration> getEffects();
method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.os.CombinedVibrationEffect.Sequential> CREATOR;
+ field @NonNull public static final android.os.Parcelable.Creator<android.os.CombinedVibration.Sequential> CREATOR;
}
- public static final class CombinedVibrationEffect.SequentialCombination {
- method @NonNull public android.os.CombinedVibrationEffect.SequentialCombination addNext(int, @NonNull android.os.VibrationEffect);
- method @NonNull public android.os.CombinedVibrationEffect.SequentialCombination addNext(int, @NonNull android.os.VibrationEffect, int);
- method @NonNull public android.os.CombinedVibrationEffect.SequentialCombination addNext(@NonNull android.os.CombinedVibrationEffect);
- method @NonNull public android.os.CombinedVibrationEffect.SequentialCombination addNext(@NonNull android.os.CombinedVibrationEffect, int);
- method @NonNull public android.os.CombinedVibrationEffect combine();
+ public static final class CombinedVibration.SequentialCombination {
+ method @NonNull public android.os.CombinedVibration.SequentialCombination addNext(int, @NonNull android.os.VibrationEffect);
+ method @NonNull public android.os.CombinedVibration.SequentialCombination addNext(int, @NonNull android.os.VibrationEffect, int);
+ method @NonNull public android.os.CombinedVibration.SequentialCombination addNext(@NonNull android.os.CombinedVibration);
+ method @NonNull public android.os.CombinedVibration.SequentialCombination addNext(@NonNull android.os.CombinedVibration, int);
+ method @NonNull public android.os.CombinedVibration combine();
}
- public static final class CombinedVibrationEffect.Stereo extends android.os.CombinedVibrationEffect {
+ public static final class CombinedVibration.Stereo extends android.os.CombinedVibration {
method public long getDuration();
method @NonNull public android.util.SparseArray<android.os.VibrationEffect> getEffects();
method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.os.CombinedVibrationEffect.Stereo> CREATOR;
+ field @NonNull public static final android.os.Parcelable.Creator<android.os.CombinedVibration.Stereo> CREATOR;
}
public class DeviceIdleManager {
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 919f1e2e85fb..1d290def0bf2 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -127,3 +127,329 @@ filegroup {
],
visibility: ["//frameworks/base/test-mock"],
}
+
+filegroup {
+ name: "libincident_aidl",
+ srcs: [
+ "android/os/IIncidentDumpCallback.aidl",
+ "android/os/IIncidentManager.aidl",
+ "android/os/IIncidentReportStatusListener.aidl",
+ ],
+}
+
+filegroup {
+ name: "libvibrator_aidl",
+ srcs: [
+ "android/os/IExternalVibrationController.aidl",
+ "android/os/IExternalVibratorService.aidl",
+ ],
+}
+
+filegroup {
+ name: "libpowermanager_aidl",
+ srcs: [
+ "android/os/Temperature.aidl",
+ "android/os/CoolingDevice.aidl",
+ "android/os/IThermalEventListener.aidl",
+ "android/os/IThermalStatusListener.aidl",
+ "android/os/IThermalService.aidl",
+ "android/os/IPowerManager.aidl",
+ ],
+}
+
+genrule {
+ name: "statslog-framework-java-gen",
+ tools: ["stats-log-api-gen"],
+ cmd: "$(location stats-log-api-gen) --java $(out) --module framework" +
+ " --javaPackage com.android.internal.util --javaClass FrameworkStatsLog --worksource",
+ out: ["com/android/internal/util/FrameworkStatsLog.java"],
+}
+
+java_library {
+ name: "uieventloggerlib",
+ srcs: [
+ "com/android/internal/logging/UiEvent.java",
+ "com/android/internal/logging/UiEventLogger.java",
+ "com/android/internal/logging/UiEventLoggerImpl.java",
+ "com/android/internal/logging/InstanceId.java",
+ "com/android/internal/logging/InstanceIdSequence.java",
+ ":statslog-framework-java-gen",
+ ],
+}
+
+filegroup {
+ name: "framework-services-net-module-wifi-shared-srcs",
+ srcs: [
+ "android/net/DhcpResults.java",
+ "android/util/LocalLog.java",
+ ],
+}
+
+// keep these files in sync with the package/Tethering/jarjar-rules.txt and
+// package/Connectivity/jarjar-rules.txt for the tethering module and connectivity module.
+filegroup {
+ name: "framework-connectivity-shared-srcs",
+ srcs: [
+ "android/util/IndentingPrintWriter.java",
+ "android/util/LocalLog.java",
+ // This should be android.util.IndentingPrintWriter, but it's not available in all branches.
+ "com/android/internal/util/IndentingPrintWriter.java",
+ "com/android/internal/util/IState.java",
+ "com/android/internal/util/MessageUtils.java",
+ "com/android/internal/util/State.java",
+ "com/android/internal/util/StateMachine.java",
+ "com/android/internal/util/WakeupMessage.java",
+ ],
+}
+
+// keep these files in sync with the apex/jobscheduler/service jarjar-rules.txt for
+// the jobscheduler module.
+filegroup {
+ name: "framework-jobscheduler-shared-srcs",
+ srcs: [
+ "com/android/internal/util/ArrayUtils.java",
+ "com/android/internal/util/BitUtils.java",
+ "com/android/internal/util/CollectionUtils.java",
+ "com/android/internal/util/ConcurrentUtils.java",
+ "com/android/internal/util/DumpUtils.java",
+ "com/android/internal/util/FastPrintWriter.java",
+ "com/android/internal/util/FastXmlSerializer.java",
+ "com/android/internal/util/FunctionalUtils.java",
+ "com/android/internal/util/ParseUtils.java",
+ "com/android/internal/util/Preconditions.java",
+ "com/android/internal/util/RingBufferIndices.java",
+ "com/android/internal/util/StatLogger.java",
+ "com/android/internal/util/XmlUtils.java",
+ ],
+}
+
+// Keep these files in sync with the apex/permission/jarjar-rules.txt for the permission module.
+filegroup {
+ name: "framework-permission-s-shared-srcs",
+ srcs: [
+ "com/android/internal/infra/AndroidFuture.java",
+ "com/android/internal/infra/ServiceConnector.java",
+ "com/android/internal/util/Preconditions.java",
+ "com/android/internal/infra/AndroidFuture.aidl",
+ "com/android/internal/infra/IAndroidFuture.aidl",
+ "android/os/HandlerExecutor.java",
+ ],
+}
+
+// Keep these files in sync with the apex/permission/jarjar-rules.txt for the permission module.
+filegroup {
+ name: "service-permission-shared-srcs",
+ srcs: [
+ "android/util/IndentingPrintWriter.java",
+ "com/android/internal/util/dump/DualDumpOutputStream.java",
+ ],
+}
+
+filegroup {
+ name: "incremental_aidl",
+ srcs: [
+ "android/os/incremental/IIncrementalServiceConnector.aidl",
+ "android/os/incremental/IncrementalFileSystemControlParcel.aidl",
+ ],
+}
+
+filegroup {
+ name: "dataloader_aidl",
+ srcs: [
+ "android/content/pm/DataLoaderParamsParcel.aidl",
+ "android/content/pm/DataLoaderType.aidl",
+ "android/content/pm/FileSystemControlParcel.aidl",
+ "android/content/pm/IDataLoader.aidl",
+ "android/content/pm/IDataLoaderManager.aidl",
+ "android/content/pm/InstallationFileParcel.aidl",
+ "android/content/pm/InstallationFileLocation.aidl",
+ "android/content/pm/IDataLoaderStatusListener.aidl",
+ "android/content/pm/IPackageInstallerSessionFileSystemConnector.aidl",
+ ],
+}
+
+filegroup {
+ name: "incremental_manager_aidl",
+ srcs: [
+ "android/os/incremental/IIncrementalService.aidl",
+ "android/os/incremental/IStorageLoadingProgressListener.aidl",
+ "android/os/incremental/IncrementalNewFileParams.aidl",
+ "android/os/incremental/IStorageHealthListener.aidl",
+ "android/os/incremental/PerUidReadTimeouts.aidl",
+ "android/os/incremental/StorageHealthCheckParams.aidl",
+ ],
+}
+
+filegroup {
+ name: "activity_manager_procstate_aidl",
+ srcs: [
+ "android/app/ProcessStateEnum.aidl",
+ ],
+}
+
+cc_defaults {
+ name: "incremental_default",
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Wextra-semi",
+ "-Werror",
+ "-Wzero-as-null-pointer-constant",
+ "-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libutils",
+ ],
+ aidl: {
+ include_dirs: [
+ "frameworks/native/aidl/binder",
+ ],
+ export_aidl_headers: true,
+ },
+}
+
+cc_library {
+ name: "libincremental_aidl-cpp",
+ srcs: [
+ ":incremental_aidl",
+ ],
+ defaults: ["incremental_default"],
+}
+
+cc_library {
+ name: "libdataloader_aidl-cpp",
+ srcs: [
+ ":dataloader_aidl",
+ ],
+ defaults: ["incremental_default"],
+ shared_libs: [
+ "libincremental_aidl-cpp",
+ ],
+}
+
+cc_library {
+ name: "libincremental_manager_aidl-cpp",
+ srcs: [
+ ":incremental_manager_aidl",
+ ],
+ defaults: ["incremental_default"],
+ shared_libs: [
+ "libincremental_aidl-cpp",
+ "libdataloader_aidl-cpp",
+ ],
+}
+
+// Build Rust bindings for PermissionController. Needed by keystore2.
+aidl_interface {
+ name: "android.os.permissions_aidl",
+ unstable: true,
+ local_include_dir: ".",
+ srcs: [
+ "android/os/IPermissionController.aidl",
+ ],
+ backend: {
+ rust: {
+ enabled: true,
+ },
+ },
+}
+
+// Avoid including Parcelable classes as we don't want to have two copies of
+// Parcelable cross the libraries. This is used by telephony-common (frameworks/opt/telephony)
+// and TeleService app (packages/services/Telephony).
+filegroup {
+ name: "framework-telephony-common-shared-srcs",
+ srcs: [
+ "android/os/RegistrantList.java",
+ "android/os/Registrant.java",
+ "android/util/IndentingPrintWriter.java",
+ "android/util/LocalLog.java",
+ "android/util/TimeUtils.java",
+ "com/android/internal/os/SomeArgs.java",
+ "com/android/internal/util/AsyncChannel.java",
+ "com/android/internal/util/AsyncService.java",
+ "com/android/internal/util/BitwiseInputStream.java",
+ "com/android/internal/util/FastXmlSerializer.java",
+ "com/android/internal/util/HexDump.java",
+ "com/android/internal/util/IState.java",
+ "com/android/internal/util/IndentingPrintWriter.java",
+ "com/android/internal/util/Preconditions.java",
+ "com/android/internal/util/State.java",
+ "com/android/internal/util/StateMachine.java",
+ "com/android/internal/util/UserIcons.java",
+ ],
+}
+
+// Avoid including Parcelable classes as we don't want to have two copies of
+// Parcelable cross the process.
+filegroup {
+ name: "framework-cellbroadcast-shared-srcs",
+ srcs: [
+ "android/os/HandlerExecutor.java",
+ "android/util/LocalLog.java",
+ "com/android/internal/util/IState.java",
+ "com/android/internal/util/Preconditions.java",
+ "com/android/internal/util/State.java",
+ "com/android/internal/util/StateMachine.java",
+ ],
+}
+
+filegroup {
+ name: "framework-ims-common-shared-srcs",
+ srcs: [
+ "android/os/RegistrantList.java",
+ "android/os/Registrant.java",
+ "com/android/internal/os/SomeArgs.java",
+ "com/android/internal/util/Preconditions.java",
+ ],
+}
+
+// utility classes statically linked into wifi-service
+filegroup {
+ name: "framework-wifi-service-shared-srcs",
+ srcs: [
+ "android/net/InterfaceConfiguration.java",
+ "android/util/BackupUtils.java",
+ "android/util/Rational.java",
+ "com/android/internal/util/FastXmlSerializer.java",
+ "com/android/internal/util/HexDump.java",
+ "com/android/internal/util/IState.java",
+ "com/android/internal/util/MessageUtils.java",
+ "com/android/internal/util/State.java",
+ "com/android/internal/util/StateMachine.java",
+ "com/android/internal/util/WakeupMessage.java",
+ ],
+ visibility: [
+ "//frameworks/opt/net/wifi/service",
+ "//packages/modules/Wifi/service",
+ ],
+}
+
+// protolog start
+filegroup {
+ name: "protolog-common-src",
+ srcs: [
+ "com/android/internal/protolog/common/**/*.java",
+ ],
+}
+
+java_library {
+ name: "protolog-lib",
+ platform_apis: true,
+ srcs: [
+ "com/android/internal/protolog/ProtoLogImpl.java",
+ "com/android/internal/protolog/ProtoLogViewerConfigReader.java",
+ ":protolog-common-src",
+ ],
+}
+
+java_library {
+ name: "protolog-groups",
+ srcs: [
+ "com/android/internal/protolog/ProtoLogGroup.java",
+ ":protolog-common-src",
+ ],
+}
+
+// protolog end
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index f0d5a893bb96..45120b694b62 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -899,6 +899,9 @@ public class Activity extends ContextThemeWrapper
/** The options for scene transition. */
ActivityOptions mPendingOptions;
+ /** Whether this activity was launched from a bubble. **/
+ boolean mLaunchedFromBubble;
+
private static final class ManagedCursor {
ManagedCursor(Cursor cursor) {
mCursor = cursor;
@@ -6790,6 +6793,25 @@ public class Activity extends ContextThemeWrapper
return getSharedPreferences(getLocalClassName(), mode);
}
+ /**
+ * Indicates whether this activity is launched from a bubble. A bubble is a floating shortcut
+ * on the screen that expands to show an activity.
+ *
+ * If your activity can be used normally or as a bubble, you might use this method to check
+ * if the activity is bubbled to modify any behaviour that might be different between the
+ * normal activity and the bubbled activity. For example, if you normally cancel the
+ * notification associated with the activity when you open the activity, you might not want to
+ * do that when you're bubbled as that would remove the bubble.
+ *
+ * @return {@code true} if the activity is launched from a bubble.
+ *
+ * @see Notification.Builder#setBubbleMetadata(Notification.BubbleMetadata)
+ * @see Notification.BubbleMetadata.Builder#Builder(String)
+ */
+ public boolean isLaunchedFromBubble() {
+ return mLaunchedFromBubble;
+ }
+
private void ensureSearchManager() {
if (mSearchManager != null) {
return;
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 006b2b5161d3..c21de62ed38e 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -323,6 +323,9 @@ public class ActivityOptions {
/** See {@link #setRemoveWithTaskOrganizer(boolean)}. */
private static final String KEY_REMOVE_WITH_TASK_ORGANIZER =
"android.activity.removeWithTaskOrganizer";
+ /** See {@link #setLaunchedFromBubble(boolean)}. */
+ private static final String KEY_LAUNCHED_FROM_BUBBLE =
+ "android.activity.launchTypeBubble";
/**
* @see #setLaunchCookie
@@ -410,6 +413,7 @@ public class ActivityOptions {
private boolean mOverrideTaskTransition;
private int mSplashScreenThemeResId;
private boolean mRemoveWithTaskOrganizer;
+ private boolean mLaunchedFromBubble;
/**
* Create an ActivityOptions specifying a custom animation to run when
@@ -1161,6 +1165,7 @@ public class ActivityOptions {
mOverrideTaskTransition = opts.getBoolean(KEY_OVERRIDE_TASK_TRANSITION);
mSplashScreenThemeResId = opts.getInt(KEY_SPLASH_SCREEN_THEME);
mRemoveWithTaskOrganizer = opts.getBoolean(KEY_REMOVE_WITH_TASK_ORGANIZER);
+ mLaunchedFromBubble = opts.getBoolean(KEY_LAUNCHED_FROM_BUBBLE);
}
/**
@@ -1647,6 +1652,23 @@ public class ActivityOptions {
}
/**
+ * Sets whether this activity is launched from a bubble.
+ * @hide
+ */
+ @TestApi
+ public void setLaunchedFromBubble(boolean fromBubble) {
+ mLaunchedFromBubble = fromBubble;
+ }
+
+ /**
+ * @return whether the activity was launched from a bubble.
+ * @hide
+ */
+ public boolean getLaunchedFromBubble() {
+ return mLaunchedFromBubble;
+ }
+
+ /**
* Update the current values in this ActivityOptions from those supplied
* in <var>otherOptions</var>. Any values
* defined in <var>otherOptions</var> replace those in the base options.
@@ -1883,6 +1905,9 @@ public class ActivityOptions {
if (mRemoveWithTaskOrganizer) {
b.putBoolean(KEY_REMOVE_WITH_TASK_ORGANIZER, mRemoveWithTaskOrganizer);
}
+ if (mLaunchedFromBubble) {
+ b.putBoolean(KEY_LAUNCHED_FROM_BUBBLE, mLaunchedFromBubble);
+ }
return b;
}
diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java
index a24f8716b1cc..627017ce0893 100644
--- a/core/java/android/app/ActivityTaskManager.java
+++ b/core/java/android/app/ActivityTaskManager.java
@@ -16,8 +16,6 @@
package android.app;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -169,35 +167,6 @@ public class ActivityTaskManager {
};
/**
- * Sets the windowing mode for a specific task. Only works on tasks of type
- * {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD}
- * @param taskId The id of the task to set the windowing mode for.
- * @param windowingMode The windowing mode to set for the task.
- * @param toTop If the task should be moved to the top once the windowing mode changes.
- * @return Whether the task was successfully put into the specified windowing mode.
- */
- @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
- public boolean setTaskWindowingMode(int taskId, int windowingMode, boolean toTop)
- throws SecurityException {
- try {
- return getService().setTaskWindowingMode(taskId, windowingMode, toTop);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Moves the input task to the primary-split-screen stack.
- * @param taskId Id of task to move.
- * @param toTop If the task and stack should be moved to the top.
- * @return Whether the task was successfully put into splitscreen.
- */
- @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
- public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, boolean toTop) {
- return setTaskWindowingMode(taskId, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, toTop);
- }
-
- /**
* Removes root tasks in the windowing modes from the system if they are of activity type
* ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
*/
@@ -367,20 +336,6 @@ public class ActivityTaskManager {
}
/**
- * Resize docked stack & its task to given stack & task bounds.
- * @param rootTaskBounds Bounds to resize stack.
- * @param taskBounds Bounds to resize task.
- */
- @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
- public void resizePrimarySplitScreen(@NonNull Rect rootTaskBounds, @NonNull Rect taskBounds) {
- try {
- getService().resizePrimarySplitScreen(rootTaskBounds, taskBounds, null, null, null);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
* Clears launch params for the given package.
* @param packageNames the names of the packages of which the launch params are to be cleared
*/
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 35890c811428..8ff14b0ad28f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -594,6 +594,9 @@ public final class ActivityThread extends ClientTransactionHandler
*/
FixedRotationAdjustments mPendingFixedRotationAdjustments;
+ /** Whether this activiy was launched from a bubble. */
+ boolean mLaunchedFromBubble;
+
@LifecycleState
private int mLifecycleState = PRE_ON_CREATE;
@@ -613,7 +616,7 @@ public final class ActivityThread extends ClientTransactionHandler
List<ReferrerIntent> pendingNewIntents, ActivityOptions activityOptions,
boolean isForward, ProfilerInfo profilerInfo, ClientTransactionHandler client,
IBinder assistToken, FixedRotationAdjustments fixedRotationAdjustments,
- IBinder shareableActivityToken) {
+ IBinder shareableActivityToken, boolean launchedFromBubble) {
this.token = token;
this.assistToken = assistToken;
this.shareableActivityToken = shareableActivityToken;
@@ -634,6 +637,7 @@ public final class ActivityThread extends ClientTransactionHandler
compatInfo);
mActivityOptions = activityOptions;
mPendingFixedRotationAdjustments = fixedRotationAdjustments;
+ mLaunchedFromBubble = launchedFromBubble;
init();
}
@@ -3549,6 +3553,7 @@ public final class ActivityThread extends ClientTransactionHandler
activity.mPendingOptions = r.mActivityOptions;
r.mActivityOptions = null;
}
+ activity.mLaunchedFromBubble = r.mLaunchedFromBubble;
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index ec7d159f707b..f7ea3815d567 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2641,9 +2641,8 @@ class ContextImpl extends Context {
// WindowContext's resources.
windowTokenClient.attachContext(windowContext);
- // Step 5. Register the window context's token to the server side to associate with a
- // window manager node.
- windowContext.registerWithServer();
+ // Step 5. Associate the WindowContext's token to a DisplayArea.
+ windowContext.attachToDisplayArea();
return windowContext;
}
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index e5a969ac98ad..346882ee7298 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -87,8 +87,6 @@ import java.util.List;
// surface exposed.
// TODO(b/174041603): Create a builder interface for things like startActivityXXX(...) to reduce
// interface duplication.
-// TODO(b/174040691): Clean-up/remove all obsolete or unused interfaces like things that should be
-// going through task organizer now.
interface IActivityTaskManager {
int startActivity(in IApplicationThread caller, in String callingPackage,
in String callingFeatureId, in Intent intent, in String resolvedType,
@@ -206,15 +204,6 @@ interface IActivityTaskManager {
boolean resizeTask(int taskId, in Rect bounds, int resizeMode);
void moveRootTaskToDisplay(int taskId, int displayId);
- /**
- * Sets the windowing mode for a specific task. Only works on tasks of type
- * {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD}
- * @param taskId The id of the task to set the windowing mode for.
- * @param windowingMode The windowing mode to set for the task.
- * @param toTop If the task should be moved to the top once the windowing mode changes.
- * @return Whether the task was successfully put into the specified windowing mode.
- */
- boolean setTaskWindowingMode(int taskId, int windowingMode, boolean toTop);
void moveTaskToRootTask(int taskId, int rootTaskId, boolean toTop);
/**
@@ -258,29 +247,6 @@ interface IActivityTaskManager {
void suppressResizeConfigChanges(boolean suppress);
- /**
- * Resizes the docked stack, and all other stacks as the result of the dock stack bounds change.
- *
- * @param dockedBounds The bounds for the docked stack.
- * @param tempDockedTaskBounds The temporary bounds for the tasks in the docked stack, which
- * might be different from the stack bounds to allow more
- * flexibility while resizing, or {@code null} if they should be the
- * same as the stack bounds.
- * @param tempDockedTaskInsetBounds The temporary bounds for the tasks to calculate the insets.
- * When resizing, we usually "freeze" the layout of a task. To
- * achieve that, we also need to "freeze" the insets, which
- * gets achieved by changing task bounds but not bounds used
- * to calculate the insets in this transient state
- * @param tempOtherTaskBounds The temporary bounds for the tasks in all other stacks, or
- * {@code null} if they should be the same as the stack bounds.
- * @param tempOtherTaskInsetBounds Like {@code tempDockedTaskInsetBounds}, but for the other
- * stacks.
- * @throws RemoteException
- */
- void resizePrimarySplitScreen(in Rect dockedBounds, in Rect tempDockedTaskBounds,
- in Rect tempDockedTaskInsetBounds,
- in Rect tempOtherTaskBounds, in Rect tempOtherTaskInsetBounds);
-
/** Returns an interface enabling the management of window organizers. */
IWindowOrganizerController getWindowOrganizerController();
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index dab5aff5c9a8..35a9f9b509cd 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -188,6 +188,8 @@ interface INotificationManager
List<ComponentName> getEnabledNotificationListeners(int userId);
ComponentName getAllowedNotificationAssistantForUser(int userId);
ComponentName getAllowedNotificationAssistant();
+ ComponentName getDefaultNotificationAssistant();
+ void resetDefaultNotificationAssistant(boolean loadFromConfig);
boolean hasEnabledNotificationListener(String packageName, int userId);
@UnsupportedAppUsage
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 0ca0b8521568..a60f1ca3cdcd 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -10205,13 +10205,8 @@ public class Notification implements Parcelable
* <p>The shortcut activity will be used when the bubble is expanded. This will display
* the shortcut activity in a floating window over the existing foreground activity.</p>
*
- * <p>When the shortcut is displayed in a bubble, there will be an intent
- * extra set on the activity, {@link Intent#EXTRA_IS_BUBBLED}
- * with {@code true}. You may check this in the onCreate of your activity via:
- *
- * <pre class="prettyprint">
- * boolean isBubbled = getIntent().getBooleanExtra(Intent.EXTRA_IS_BUBBLED, false);
- * </pre>
+ * <p>When the activity is launched from a bubble,
+ * {@link Activity#isLaunchedFromBubble()} will return with {@code true}.
* </p>
*
* <p>If the shortcut has not been published when the bubble notification is sent,
@@ -10242,13 +10237,8 @@ public class Notification implements Parcelable
* app content in a floating window over the existing foreground activity. The intent
* should point to a resizable activity. </p>
*
- * <p>When the activity is displayed in a bubble, there will be an intent
- * extra set on the activity, {@link Intent#EXTRA_IS_BUBBLED}
- * with {@code true}. You may check this in the onCreate of your activity via:
- *
- * <pre class="prettyprint">
- * boolean isBubbled = getIntent().getBooleanExtra(Intent.EXTRA_IS_BUBBLED, false);
- * </pre>
+ * <p>When the activity is launched from a bubble,
+ * {@link Activity#isLaunchedFromBubble()} will return with {@code true}.
* </p>
*
* @throws NullPointerException if intent is null.
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 47a9fbb5fe4a..91dad2a1f13c 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -158,12 +158,14 @@ import android.os.IBatteryPropertiesRegistrar;
import android.os.IBinder;
import android.os.IDumpstate;
import android.os.IHardwarePropertiesManager;
+import android.os.IHintManager;
import android.os.IPowerManager;
import android.os.IRecoverySystem;
import android.os.ISystemUpdateManager;
import android.os.IThermalService;
import android.os.IUserManager;
import android.os.IncidentManager;
+import android.os.PerformanceHintManager;
import android.os.PowerManager;
import android.os.RecoverySystem;
import android.os.ServiceManager;
@@ -592,6 +594,17 @@ public final class SystemServiceRegistry {
ctx.mMainThread.getHandler());
}});
+ registerService(Context.PERFORMANCE_HINT_SERVICE, PerformanceHintManager.class,
+ new CachedServiceFetcher<PerformanceHintManager>() {
+ @Override
+ public PerformanceHintManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ IBinder hintBinder = ServiceManager.getServiceOrThrow(
+ Context.PERFORMANCE_HINT_SERVICE);
+ IHintManager hintService = IHintManager.Stub.asInterface(hintBinder);
+ return new PerformanceHintManager(hintService);
+ }});
+
registerService(Context.RECOVERY_SERVICE, RecoverySystem.class,
new CachedServiceFetcher<RecoverySystem>() {
@Override
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 843aa2ecb492..7af9482b0010 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -991,8 +991,8 @@ public class DevicePolicyManager {
* <p>Use only for device owner provisioning.
* @see #ACTION_GET_PROVISIONING_MODE
*/
- public static final String EXTRA_PROVISIONING_PERMISSION_GRANT_OPT_OUT =
- "android.app.extra.PROVISIONING_PERMISSION_GRANT_OPT_OUT";
+ public static final String EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT =
+ "android.app.extra.PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT";
/**
* A String extra holding the URL-safe base64 encoded SHA-256 checksum of any signature of the
@@ -5297,7 +5297,8 @@ public class DevicePolicyManager {
* {@link #WIPE_EXTERNAL_STORAGE}, {@link #WIPE_RESET_PROTECTION_DATA},
* {@link #WIPE_EUICC} and {@link #WIPE_SILENTLY}.
* @throws SecurityException if the calling application does not own an active administrator
- * that uses {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA}
+ * that uses {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA} or is not granted the
+ * {@link android.Manifest.permission#MASTER_CLEAR} permission.
*/
public void wipeData(int flags) {
wipeDataInternal(flags, "");
@@ -5325,7 +5326,8 @@ public class DevicePolicyManager {
* @param reason a string that contains the reason for wiping data, which can be
* presented to the user.
* @throws SecurityException if the calling application does not own an active administrator
- * that uses {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA}
+ * that uses {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA} or is not granted the
+ * {@link android.Manifest.permission#MASTER_CLEAR} permission.
* @throws IllegalArgumentException if the input reason string is null or empty, or if
* {@link #WIPE_SILENTLY} is set.
*/
@@ -10121,45 +10123,51 @@ public class DevicePolicyManager {
}
/**
- * Sets whether enterprise network preference is enabled on the work profile.
+ * Sets whether preferential network service is enabled on the work profile.
+ * For example, an organization can have a deal/agreement with a carrier that all of
+ * the work data from its employees’ devices will be sent via a network service dedicated
+ * for enterprise use.
*
- * For example, a corporation can have a deal/agreement with a carrier that all of its
- * employees’ devices use data on a network preference dedicated for enterprise use.
+ * An example of a supported preferential network service is the Enterprise
+ * slice on 5G networks.
*
- * By default, enterprise network preference is enabled on the work profile on supported
+ * By default, preferential network service is enabled on the work profile on supported
* carriers and devices. Admins can explicitly disable it with this API.
+ * On fully-managed devices this method is unsupported because all traffic is considered
+ * work traffic.
*
* <p>This method can only be called by the profile owner of a managed profile.
- *
- * @param enabled whether enterprise network preference should be enabled.
+ * @param enabled whether preferential network service should be enabled.
* @throws SecurityException if the caller is not the profile owner.
**/
- public void setEnterpriseNetworkPreferenceEnabled(boolean enabled) {
- throwIfParentInstance("setEnterpriseNetworkPreferenceEnabled");
- if (mService != null) {
- try {
- mService.setEnterpriseNetworkPreferenceEnabled(enabled);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ public void setPreferentialNetworkServiceEnabled(boolean enabled) {
+ throwIfParentInstance("setPreferentialNetworkServiceEnabled");
+ if (mService == null) {
+ return;
+ }
+
+ try {
+ mService.setPreferentialNetworkServiceEnabled(enabled);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
/**
- * Indicates whether whether enterprise network preference is enabled.
+ * Indicates whether preferential network service is enabled.
*
* <p>This method can be called by the profile owner of a managed profile.
*
- * @return whether whether enterprise network preference is enabled.
+ * @return whether preferential network service is enabled.
* @throws SecurityException if the caller is not the profile owner.
*/
- public boolean isEnterpriseNetworkPreferenceEnabled() {
- throwIfParentInstance("isEnterpriseNetworkPreferenceEnabled");
+ public boolean isPreferentialNetworkServiceEnabled() {
+ throwIfParentInstance("isPreferentialNetworkServiceEnabled");
if (mService == null) {
return false;
}
try {
- return mService.isEnterpriseNetworkPreferenceEnabled(myUserId());
+ return mService.isPreferentialNetworkServiceEnabled(myUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -10963,8 +10971,8 @@ public class DevicePolicyManager {
* <p>
* A device owner, by default, may continue granting these permissions. However, for increased
* user control, the admin may opt out of controlling grants for these permissions by including
- * {@link #EXTRA_PROVISIONING_PERMISSION_GRANT_OPT_OUT} in the provisioning parameters. In that
- * case the device owner's control will be limited do denying these permissions.
+ * {@link #EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT} in the provisioning parameters.
+ * In that case the device owner's control will be limited do denying these permissions.
* <p>
* Attempts by the admin to grant these permissions, when the admin is restricted from doing
* so, will be silently ignored (no exception will be thrown).
diff --git a/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java b/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java
index 9eb9a7bdad07..80655ddb886f 100644
--- a/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java
+++ b/core/java/android/app/admin/FullyManagedDeviceProvisioningParams.java
@@ -229,7 +229,7 @@ public final class FullyManagedDeviceProvisioningParams implements Parcelable {
/**
* Marks that the Device Owner may grant permissions related to device sensors.
- * See {@link DevicePolicyManager#EXTRA_PROVISIONING_PERMISSION_GRANT_OPT_OUT}.
+ * See {@link DevicePolicyManager#EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT}.
*/
@NonNull
@SuppressLint("MissingGetterMatchingBuilder")
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 8a8c69c10379..05b0be4c5813 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -274,8 +274,8 @@ interface IDevicePolicyManager {
void setSecondaryLockscreenEnabled(in ComponentName who, boolean enabled);
boolean isSecondaryLockscreenEnabled(in UserHandle userHandle);
- void setEnterpriseNetworkPreferenceEnabled(in boolean enabled);
- boolean isEnterpriseNetworkPreferenceEnabled(int userHandle);
+ void setPreferentialNetworkServiceEnabled(in boolean enabled);
+ boolean isPreferentialNetworkServiceEnabled(int userHandle);
void setLockTaskPackages(in ComponentName who, in String[] packages);
String[] getLockTaskPackages(in ComponentName who);
diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java
index 9f8fcc15b747..e281a0268184 100644
--- a/core/java/android/app/servertransaction/LaunchActivityItem.java
+++ b/core/java/android/app/servertransaction/LaunchActivityItem.java
@@ -72,6 +72,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
private ProfilerInfo mProfilerInfo;
private IBinder mAssistToken;
private IBinder mShareableActivityToken;
+ private boolean mLaunchedFromBubble;
/**
* It is only non-null if the process is the first time to launch activity. It is only an
* optimization for quick look up of the interface so the field is ignored for comparison.
@@ -96,7 +97,8 @@ public class LaunchActivityItem extends ClientTransactionItem {
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,
- client, mAssistToken, mFixedRotationAdjustments, mShareableActivityToken);
+ client, mAssistToken, mFixedRotationAdjustments, mShareableActivityToken,
+ mLaunchedFromBubble);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -120,7 +122,8 @@ public class LaunchActivityItem extends ClientTransactionItem {
List<ReferrerIntent> pendingNewIntents, ActivityOptions activityOptions,
boolean isForward, ProfilerInfo profilerInfo, IBinder assistToken,
IActivityClientController activityClientController,
- FixedRotationAdjustments fixedRotationAdjustments, IBinder shareableActivityToken) {
+ FixedRotationAdjustments fixedRotationAdjustments, IBinder shareableActivityToken,
+ boolean launchedFromBubble) {
LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class);
if (instance == null) {
instance = new LaunchActivityItem();
@@ -128,7 +131,8 @@ public class LaunchActivityItem extends ClientTransactionItem {
setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer,
voiceInteractor, procState, state, persistentState, pendingResults,
pendingNewIntents, activityOptions, isForward, profilerInfo, assistToken,
- activityClientController, fixedRotationAdjustments, shareableActivityToken);
+ activityClientController, fixedRotationAdjustments, shareableActivityToken,
+ launchedFromBubble);
return instance;
}
@@ -136,7 +140,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
@Override
public void recycle() {
setValues(this, null, 0, null, null, null, null, null, null, 0, null, null, null, null,
- null, false, null, null, null, null, null);
+ null, false, null, null, null, null, null, false);
ObjectPool.recycle(this);
}
@@ -166,6 +170,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
dest.writeStrongInterface(mActivityClientController);
dest.writeTypedObject(mFixedRotationAdjustments, flags);
dest.writeStrongBinder(mShareableActivityToken);
+ dest.writeBoolean(mLaunchedFromBubble);
}
/** Read from Parcel. */
@@ -183,7 +188,8 @@ public class LaunchActivityItem extends ClientTransactionItem {
in.readTypedObject(ProfilerInfo.CREATOR),
in.readStrongBinder(),
IActivityClientController.Stub.asInterface(in.readStrongBinder()),
- in.readTypedObject(FixedRotationAdjustments.CREATOR), in.readStrongBinder());
+ in.readTypedObject(FixedRotationAdjustments.CREATOR), in.readStrongBinder(),
+ in.readBoolean());
}
public static final @NonNull Creator<LaunchActivityItem> CREATOR =
@@ -293,7 +299,8 @@ public class LaunchActivityItem extends ClientTransactionItem {
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
ActivityOptions activityOptions, boolean isForward, ProfilerInfo profilerInfo,
IBinder assistToken, IActivityClientController activityClientController,
- FixedRotationAdjustments fixedRotationAdjustments, IBinder shareableActivityToken) {
+ FixedRotationAdjustments fixedRotationAdjustments, IBinder shareableActivityToken,
+ boolean launchedFromBubble) {
instance.mIntent = intent;
instance.mIdent = ident;
instance.mInfo = info;
@@ -314,5 +321,6 @@ public class LaunchActivityItem extends ClientTransactionItem {
instance.mActivityClientController = activityClientController;
instance.mFixedRotationAdjustments = fixedRotationAdjustments;
instance.mShareableActivityToken = shareableActivityToken;
+ instance.mLaunchedFromBubble = launchedFromBubble;
}
}
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 0116db04fad4..0e25d8acf3db 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -439,24 +439,22 @@ public final class CompanionDeviceManager {
/**
* Associates given device with given app for the given user directly, without UI prompt.
*
- * @return whether successful
- *
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES)
- public boolean associate(
+ public void associate(
@NonNull String packageName,
@NonNull MacAddress macAddress) {
if (!checkFeaturePresent()) {
- return false;
+ return;
}
Objects.requireNonNull(packageName, "package name cannot be null");
Objects.requireNonNull(macAddress, "mac address cannot be null");
UserHandle user = android.os.Process.myUserHandle();
try {
- return mService.createAssociation(
+ mService.createAssociation(
packageName, macAddress.toString(), user.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl
index 83db35872f74..cc3749cc2a24 100644
--- a/core/java/android/companion/ICompanionDeviceManager.aidl
+++ b/core/java/android/companion/ICompanionDeviceManager.aidl
@@ -52,5 +52,5 @@ interface ICompanionDeviceManager {
boolean canPairWithoutPrompt(in String packageName, in String deviceMacAddress, int userId);
- boolean createAssociation(in String packageName, in String macAddress, int userId);
+ void createAssociation(in String packageName, in String macAddress, int userId);
}
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 82842039c310..7e1df1b0e59c 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -2655,7 +2655,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
*/
@NonNull
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public static Uri createContentUriAsUser(
+ public static Uri createContentUriForUser(
@NonNull Uri contentUri, @NonNull UserHandle userHandle) {
if (!ContentResolver.SCHEME_CONTENT.equals(contentUri.getScheme())) {
throw new IllegalArgumentException(String.format(
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 1226858bba71..09ac8103c526 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4128,9 +4128,11 @@ public abstract class Context {
* Use with {@link #getSystemService(String)} to retrieve a {@link android.os.Vibrator} for
* interacting with the vibration hardware.
*
+ * @deprecated Use {@link android.os.VibratorManager} to retrieve the default system vibrator.
* @see #getSystemService(String)
* @see android.os.Vibrator
*/
+ @Deprecated
public static final String VIBRATOR_SERVICE = "vibrator";
/**
@@ -5226,6 +5228,14 @@ public abstract class Context {
/**
* Use with {@link #getSystemService(String)} to retrieve a
+ * {@link android.os.PerformanceHintManager} for accessing the performance hinting service.
+ *
+ * @see #getSystemService(String)
+ */
+ public static final String PERFORMANCE_HINT_SERVICE = "performance_hint";
+
+ /**
+ * Use with {@link #getSystemService(String)} to retrieve a
* {@link android.content.pm.ShortcutManager} for accessing the launcher shortcut service.
*
* @see #getSystemService(String)
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index a482b8c189cd..9ad017c5f9c6 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -6177,16 +6177,6 @@ public class Intent implements Parcelable, Cloneable {
*/
public static final String EXTRA_UNSTARTABLE_REASON = "android.intent.extra.UNSTARTABLE_REASON";
- /**
- * A boolean extra indicating whether an activity is bubbled. Set on the shortcut or
- * pending intent provided for the bubble. If the extra is not present or false, then it is not
- * bubbled.
- *
- * @see android.app.Notification.Builder#setBubbleMetadata(Notification.BubbleMetadata)
- * @see android.app.Notification.BubbleMetadata.Builder#Builder(String)
- */
- public static final String EXTRA_IS_BUBBLED = "android.intent.extra.IS_BUBBLED";
-
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Intent flags (see mFlags variable).
diff --git a/core/java/android/content/pm/AppSearchShortcutInfo.java b/core/java/android/content/pm/AppSearchShortcutInfo.java
index b2478ca12191..6d5829c175b5 100644
--- a/core/java/android/content/pm/AppSearchShortcutInfo.java
+++ b/core/java/android/content/pm/AppSearchShortcutInfo.java
@@ -52,6 +52,7 @@ public class AppSearchShortcutInfo extends GenericDocument {
/** The name of the schema type for {@link ShortcutInfo} documents.*/
public static final String SCHEMA_TYPE = "Shortcut";
+ public static final int SCHEMA_VERSION = 1;
public static final String KEY_ACTIVITY = "activity";
public static final String KEY_SHORT_LABEL = "shortLabel";
@@ -163,8 +164,10 @@ public class AppSearchShortcutInfo extends GenericDocument {
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
.build()
- ).addProperty(new AppSearchSchema.Int64PropertyConfig.Builder(KEY_RANK)
+ ).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_RANK)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+ .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+ .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
.build()
).addProperty(new AppSearchSchema.Int64PropertyConfig.Builder(KEY_IMPLICIT_RANK)
@@ -175,8 +178,10 @@ public class AppSearchShortcutInfo extends GenericDocument {
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.build()
- ).addProperty(new AppSearchSchema.Int64PropertyConfig.Builder(KEY_FLAGS)
+ ).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_FLAGS)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+ .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+ .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
.build()
).addProperty(new AppSearchSchema.Int64PropertyConfig.Builder(KEY_ICON_RES_ID)
@@ -201,12 +206,111 @@ public class AppSearchShortcutInfo extends GenericDocument {
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
.build()
- ).addProperty(new AppSearchSchema.Int64PropertyConfig.Builder(KEY_DISABLED_REASON)
+ ).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_DISABLED_REASON)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
+ .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+ .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
.build()
).build();
+ /**
+ * The string representation of every flag within {@link ShortcutInfo}. Note that its value
+ * needs to be camelCase since AppSearch's tokenizer will break the word when it sees
+ * underscore.
+ */
+ private static final String IS_DYNAMIC = "Dyn";
+ private static final String NOT_DYNAMIC = "nDyn";
+ private static final String IS_PINNED = "Pin";
+ private static final String NOT_PINNED = "nPin";
+ private static final String HAS_ICON_RES = "IcR";
+ private static final String NO_ICON_RES = "nIcR";
+ private static final String HAS_ICON_FILE = "IcF";
+ private static final String NO_ICON_FILE = "nIcF";
+ private static final String IS_KEY_FIELD_ONLY = "Key";
+ private static final String NOT_KEY_FIELD_ONLY = "nKey";
+ private static final String IS_MANIFEST = "Man";
+ private static final String NOT_MANIFEST = "nMan";
+ private static final String IS_DISABLED = "Dis";
+ private static final String NOT_DISABLED = "nDis";
+ private static final String ARE_STRINGS_RESOLVED = "Str";
+ private static final String NOT_STRINGS_RESOLVED = "nStr";
+ private static final String IS_IMMUTABLE = "Im";
+ private static final String NOT_IMMUTABLE = "nIm";
+ private static final String HAS_ADAPTIVE_BITMAP = "IcA";
+ private static final String NO_ADAPTIVE_BITMAP = "nIcA";
+ private static final String IS_RETURNED_BY_SERVICE = "Rets";
+ private static final String NOT_RETURNED_BY_SERVICE = "nRets";
+ private static final String HAS_ICON_FILE_PENDING_SAVE = "Pens";
+ private static final String NO_ICON_FILE_PENDING_SAVE = "nPens";
+ private static final String IS_SHADOW = "Sdw";
+ private static final String NOT_SHADOW = "nSdw";
+ private static final String IS_LONG_LIVED = "Liv";
+ private static final String NOT_LONG_LIVED = "nLiv";
+ private static final String HAS_ICON_URI = "IcU";
+ private static final String NO_ICON_URI = "nIcU";
+ private static final String IS_CACHED_NOTIFICATION = "CaN";
+ private static final String NOT_CACHED_NOTIFICATION = "nCaN";
+ private static final String IS_CACHED_BUBBLE = "CaB";
+ private static final String NOT_CACHED_BUBBLE = "nCaB";
+ private static final String IS_CACHED_PEOPLE_TITLE = "CaPT";
+ private static final String NOT_CACHED_PEOPLE_TITLE = "nCaPT";
+
+ /**
+ * Following flags are not store within ShortcutInfo, but book-keeping states to reduce search
+ * space when performing queries against AppSearch.
+ */
+ private static final String HAS_BITMAP_PATH = "hBiP";
+ private static final String HAS_STRING_RESOURCE = "hStr";
+ private static final String HAS_NON_ZERO_RANK = "hRan";
+
+ public static final String QUERY_IS_DYNAMIC = KEY_FLAGS + ":" + IS_DYNAMIC;
+ public static final String QUERY_IS_NOT_DYNAMIC = KEY_FLAGS + ":" + NOT_DYNAMIC;
+ public static final String QUERY_IS_PINNED = KEY_FLAGS + ":" + IS_PINNED;
+ public static final String QUERY_IS_NOT_PINNED = KEY_FLAGS + ":" + NOT_PINNED;
+ public static final String QUERY_IS_MANIFEST = KEY_FLAGS + ":" + IS_MANIFEST;
+ public static final String QUERY_IS_NOT_MANIFEST = KEY_FLAGS + ":" + NOT_MANIFEST;
+ public static final String QUERY_IS_PINNED_AND_ENABLED =
+ "(" + KEY_FLAGS + ":" + IS_PINNED + " " + KEY_FLAGS + ":" + NOT_DISABLED + ")";
+ public static final String QUERY_IS_CACHED =
+ "(" + KEY_FLAGS + ":" + IS_CACHED_NOTIFICATION + " OR "
+ + KEY_FLAGS + ":" + IS_CACHED_BUBBLE + " OR "
+ + KEY_FLAGS + ":" + IS_CACHED_PEOPLE_TITLE + ")";
+ public static final String QUERY_IS_NOT_CACHED =
+ "(" + KEY_FLAGS + ":" + NOT_CACHED_NOTIFICATION + " "
+ + KEY_FLAGS + ":" + NOT_CACHED_BUBBLE + " "
+ + KEY_FLAGS + ":" + NOT_CACHED_PEOPLE_TITLE + ")";
+ public static final String QUERY_IS_FLOATING =
+ "((" + IS_PINNED + " OR " + QUERY_IS_CACHED + ") "
+ + QUERY_IS_NOT_DYNAMIC + " " + QUERY_IS_NOT_MANIFEST + ")";
+ public static final String QUERY_IS_NOT_FLOATING =
+ "((" + QUERY_IS_NOT_PINNED + " " + QUERY_IS_NOT_CACHED + ") OR "
+ + QUERY_IS_DYNAMIC + " OR " + QUERY_IS_MANIFEST + ")";
+ public static final String QUERY_IS_VISIBLE_TO_PUBLISHER =
+ "(" + KEY_DISABLED_REASON + ":" + ShortcutInfo.DISABLED_REASON_NOT_DISABLED
+ + " OR " + KEY_DISABLED_REASON + ":"
+ + ShortcutInfo.DISABLED_REASON_BY_APP
+ + " OR " + KEY_DISABLED_REASON + ":"
+ + ShortcutInfo.DISABLED_REASON_APP_CHANGED
+ + " OR " + KEY_DISABLED_REASON + ":"
+ + ShortcutInfo.DISABLED_REASON_UNKNOWN + ")";
+ public static final String QUERY_DISABLED_REASON_VERSION_LOWER =
+ KEY_DISABLED_REASON + ":" + ShortcutInfo.DISABLED_REASON_VERSION_LOWER;
+ public static final String QUERY_IS_NON_MANIFEST_VISIBLE =
+ "(" + QUERY_IS_NOT_MANIFEST + " " + QUERY_IS_VISIBLE_TO_PUBLISHER + " ("
+ + QUERY_IS_PINNED + " OR " + QUERY_IS_CACHED + " OR " + QUERY_IS_DYNAMIC + "))";
+ public static final String QUERY_IS_VISIBLE_CACHED_OR_PINNED =
+ "(" + QUERY_IS_VISIBLE_TO_PUBLISHER + " " + QUERY_IS_DYNAMIC
+ + " (" + QUERY_IS_CACHED + " OR " + QUERY_IS_PINNED + "))";
+ public static final String QUERY_IS_VISIBLE_PINNED_ONLY =
+ "(" + QUERY_IS_VISIBLE_TO_PUBLISHER + " " + QUERY_IS_PINNED + " " + QUERY_IS_NOT_CACHED
+ + " " + QUERY_IS_NOT_DYNAMIC + " " + QUERY_IS_NOT_MANIFEST + ")";
+ public static final String QUERY_HAS_BITMAP_PATH = KEY_FLAGS + ":" + HAS_BITMAP_PATH;
+ public static final String QUERY_HAS_STRING_RESOURCE = KEY_FLAGS + ":" + HAS_STRING_RESOURCE;
+ public static final String QUERY_HAS_NON_ZERO_RANK = KEY_FLAGS + ":" + HAS_NON_ZERO_RANK;
+ public static final String QUERY_IS_FLOATING_AND_HAS_RANK =
+ "(" + QUERY_IS_FLOATING + " " + QUERY_HAS_NON_ZERO_RANK + ")";
+
public AppSearchShortcutInfo(@NonNull GenericDocument document) {
super(document);
}
@@ -304,16 +408,16 @@ public class AppSearchShortcutInfo extends GenericDocument {
final Person[] persons = parsePerson(getPropertyDocumentArray(KEY_PERSON));
final String locusIdString = getPropertyString(KEY_LOCUS_ID);
final LocusId locusId = locusIdString == null ? null : new LocusId(locusIdString);
- final int rank = (int) getPropertyLong(KEY_RANK);
+ final int rank = Integer.parseInt(getPropertyString(KEY_RANK));
final int implicitRank = (int) getPropertyLong(KEY_IMPLICIT_RANK);
final byte[] extrasByte = getPropertyBytes(KEY_EXTRAS);
final PersistableBundle extras = transformToPersistableBundle(extrasByte);
- final int flags = parseFlags(getPropertyLongArray(KEY_FLAGS));
+ final int flags = parseFlags(getPropertyStringArray(KEY_FLAGS));
final int iconResId = (int) getPropertyLong(KEY_ICON_RES_ID);
final String iconResName = getPropertyString(KEY_ICON_RES_NAME);
final String iconUri = getPropertyString(KEY_ICON_URI);
final String bitmapPath = getPropertyString(KEY_BITMAP_PATH);
- final int disabledReason = (int) getPropertyLong(KEY_DISABLED_REASON);
+ final int disabledReason = Integer.parseInt(getPropertyString(KEY_DISABLED_REASON));
final ShortcutInfo si = new ShortcutInfo(
userId, getUri(), packageName, activity, icon, shortLabel, shortLabelResId,
shortLabelResName, longLabel, longLabelResId, longLabelResName, disabledMessage,
@@ -344,6 +448,9 @@ public class AppSearchShortcutInfo extends GenericDocument {
@VisibleForTesting
public static class Builder extends GenericDocument.Builder<Builder> {
+ private List<String> mFlags = new ArrayList<>(1);
+ private boolean mHasStringResource = false;
+
public Builder(String packageName, String id) {
super(/*namespace=*/ packageName, id, SCHEMA_TYPE);
}
@@ -386,8 +493,11 @@ public class AppSearchShortcutInfo extends GenericDocument {
* @hide
*/
@NonNull
- public Builder setShortLabelResId(@Nullable final int shortLabelResId) {
+ public Builder setShortLabelResId(final int shortLabelResId) {
setPropertyLong(KEY_SHORT_LABEL_RES_ID, shortLabelResId);
+ if (shortLabelResId != 0) {
+ mHasStringResource = true;
+ }
return this;
}
@@ -417,8 +527,11 @@ public class AppSearchShortcutInfo extends GenericDocument {
* @hide
*/
@NonNull
- public Builder setLongLabelResId(@Nullable final int longLabelResId) {
+ public Builder setLongLabelResId(final int longLabelResId) {
setPropertyLong(KEY_LONG_LABEL_RES_ID, longLabelResId);
+ if (longLabelResId != 0) {
+ mHasStringResource = true;
+ }
return this;
}
@@ -448,8 +561,11 @@ public class AppSearchShortcutInfo extends GenericDocument {
* @hide
*/
@NonNull
- public Builder setDisabledMessageResId(@Nullable final int disabledMessageResId) {
+ public Builder setDisabledMessageResId(final int disabledMessageResId) {
setPropertyLong(KEY_DISABLED_MESSAGE_RES_ID, disabledMessageResId);
+ if (disabledMessageResId != 0) {
+ mHasStringResource = true;
+ }
return this;
}
@@ -546,7 +662,10 @@ public class AppSearchShortcutInfo extends GenericDocument {
@NonNull
public Builder setRank(final int rank) {
Preconditions.checkArgument((0 <= rank), "Rank cannot be negative");
- setPropertyLong(KEY_RANK, rank);
+ setPropertyString(KEY_RANK, String.valueOf(rank));
+ if (rank != 0) {
+ mFlags.add(HAS_NON_ZERO_RANK);
+ }
return this;
}
@@ -574,7 +693,10 @@ public class AppSearchShortcutInfo extends GenericDocument {
* @hide
*/
public Builder setFlags(@ShortcutInfo.ShortcutFlags final int flags) {
- setPropertyLong(KEY_FLAGS, flattenFlags(flags));
+ final String[] flagArray = flattenFlags(flags);
+ if (flagArray != null && flagArray.length > 0) {
+ mFlags.addAll(Arrays.asList(flagArray));
+ }
return this;
}
@@ -603,6 +725,7 @@ public class AppSearchShortcutInfo extends GenericDocument {
public Builder setBitmapPath(@Nullable final String bitmapPath) {
if (!TextUtils.isEmpty(bitmapPath)) {
setPropertyString(KEY_BITMAP_PATH, bitmapPath);
+ mFlags.add(HAS_BITMAP_PATH);
}
return this;
}
@@ -621,7 +744,7 @@ public class AppSearchShortcutInfo extends GenericDocument {
* @hide
*/
public Builder setDisabledReason(@ShortcutInfo.DisabledReason final int disabledReason) {
- setPropertyLong(KEY_DISABLED_REASON, disabledReason);
+ setPropertyString(KEY_DISABLED_REASON, String.valueOf(disabledReason));
return this;
}
@@ -631,6 +754,10 @@ public class AppSearchShortcutInfo extends GenericDocument {
@NonNull
@Override
public AppSearchShortcutInfo build() {
+ if (mHasStringResource) {
+ mFlags.add(HAS_STRING_RESOURCE);
+ }
+ setPropertyString(KEY_FLAGS, mFlags.toArray(new String[0]));
return new AppSearchShortcutInfo(super.build());
}
}
@@ -682,20 +809,115 @@ public class AppSearchShortcutInfo extends GenericDocument {
}
}
- private static long[] flattenFlags(@ShortcutInfo.ShortcutFlags final int flags) {
- final List<Integer> flattenedFlags = new ArrayList<>();
- flattenedFlags.add(0);
+ private static String[] flattenFlags(@ShortcutInfo.ShortcutFlags final int flags) {
+ final List<String> flattenedFlags = new ArrayList<>();
for (int i = 0; i < 31; i++) {
final int mask = 1 << i;
- if ((flags & mask) != 0) {
- flattenedFlags.add(mask);
+ final String value = flagToString(flags, mask);
+ if (value != null) {
+ flattenedFlags.add(value);
}
}
- return flattenedFlags.stream().mapToLong(i -> i).toArray();
+ return flattenedFlags.toArray(new String[0]);
+ }
+
+ @Nullable
+ private static String flagToString(
+ @ShortcutInfo.ShortcutFlags final int flags, final int mask) {
+ switch (mask) {
+ case ShortcutInfo.FLAG_DYNAMIC:
+ return (flags & mask) != 0 ? IS_DYNAMIC : NOT_DYNAMIC;
+ case ShortcutInfo.FLAG_PINNED:
+ return (flags & mask) != 0 ? IS_PINNED : NOT_PINNED;
+ case ShortcutInfo.FLAG_HAS_ICON_RES:
+ return (flags & mask) != 0 ? HAS_ICON_RES : NO_ICON_RES;
+ case ShortcutInfo.FLAG_HAS_ICON_FILE:
+ return (flags & mask) != 0 ? HAS_ICON_FILE : NO_ICON_FILE;
+ case ShortcutInfo.FLAG_KEY_FIELDS_ONLY:
+ return (flags & mask) != 0 ? IS_KEY_FIELD_ONLY : NOT_KEY_FIELD_ONLY;
+ case ShortcutInfo.FLAG_MANIFEST:
+ return (flags & mask) != 0 ? IS_MANIFEST : NOT_MANIFEST;
+ case ShortcutInfo.FLAG_DISABLED:
+ return (flags & mask) != 0 ? IS_DISABLED : NOT_DISABLED;
+ case ShortcutInfo.FLAG_STRINGS_RESOLVED:
+ return (flags & mask) != 0 ? ARE_STRINGS_RESOLVED : NOT_STRINGS_RESOLVED;
+ case ShortcutInfo.FLAG_IMMUTABLE:
+ return (flags & mask) != 0 ? IS_IMMUTABLE : NOT_IMMUTABLE;
+ case ShortcutInfo.FLAG_ADAPTIVE_BITMAP:
+ return (flags & mask) != 0 ? HAS_ADAPTIVE_BITMAP : NO_ADAPTIVE_BITMAP;
+ case ShortcutInfo.FLAG_RETURNED_BY_SERVICE:
+ return (flags & mask) != 0 ? IS_RETURNED_BY_SERVICE : NOT_RETURNED_BY_SERVICE;
+ case ShortcutInfo.FLAG_ICON_FILE_PENDING_SAVE:
+ return (flags & mask) != 0 ? HAS_ICON_FILE_PENDING_SAVE : NO_ICON_FILE_PENDING_SAVE;
+ case ShortcutInfo.FLAG_SHADOW:
+ return (flags & mask) != 0 ? IS_SHADOW : NOT_SHADOW;
+ case ShortcutInfo.FLAG_LONG_LIVED:
+ return (flags & mask) != 0 ? IS_LONG_LIVED : NOT_LONG_LIVED;
+ case ShortcutInfo.FLAG_HAS_ICON_URI:
+ return (flags & mask) != 0 ? HAS_ICON_URI : NO_ICON_URI;
+ case ShortcutInfo.FLAG_CACHED_NOTIFICATIONS:
+ return (flags & mask) != 0 ? IS_CACHED_NOTIFICATION : NOT_CACHED_NOTIFICATION;
+ case ShortcutInfo.FLAG_CACHED_BUBBLES:
+ return (flags & mask) != 0 ? IS_CACHED_BUBBLE : NOT_CACHED_BUBBLE;
+ case ShortcutInfo.FLAG_CACHED_PEOPLE_TILE:
+ return (flags & mask) != 0 ? IS_CACHED_PEOPLE_TITLE : NOT_CACHED_PEOPLE_TITLE;
+ default:
+ return null;
+ }
}
- private static int parseFlags(final long[] flags) {
- return (int) Arrays.stream(flags).reduce((p, v) -> p | v).getAsLong();
+ private static int parseFlags(@Nullable final String[] flags) {
+ if (flags == null) {
+ return 0;
+ }
+ int ret = 0;
+ for (int i = 0; i < flags.length; i++) {
+ ret = ret | parseFlag(flags[i]);
+ }
+ return ret;
+ }
+
+ private static int parseFlag(final String value) {
+ switch (value) {
+ case IS_DYNAMIC:
+ return ShortcutInfo.FLAG_DYNAMIC;
+ case IS_PINNED:
+ return ShortcutInfo.FLAG_PINNED;
+ case HAS_ICON_RES:
+ return ShortcutInfo.FLAG_HAS_ICON_RES;
+ case HAS_ICON_FILE:
+ return ShortcutInfo.FLAG_HAS_ICON_FILE;
+ case IS_KEY_FIELD_ONLY:
+ return ShortcutInfo.FLAG_KEY_FIELDS_ONLY;
+ case IS_MANIFEST:
+ return ShortcutInfo.FLAG_MANIFEST;
+ case IS_DISABLED:
+ return ShortcutInfo.FLAG_DISABLED;
+ case ARE_STRINGS_RESOLVED:
+ return ShortcutInfo.FLAG_STRINGS_RESOLVED;
+ case IS_IMMUTABLE:
+ return ShortcutInfo.FLAG_IMMUTABLE;
+ case HAS_ADAPTIVE_BITMAP:
+ return ShortcutInfo.FLAG_ADAPTIVE_BITMAP;
+ case IS_RETURNED_BY_SERVICE:
+ return ShortcutInfo.FLAG_RETURNED_BY_SERVICE;
+ case HAS_ICON_FILE_PENDING_SAVE:
+ return ShortcutInfo.FLAG_ICON_FILE_PENDING_SAVE;
+ case IS_SHADOW:
+ return ShortcutInfo.FLAG_SHADOW;
+ case IS_LONG_LIVED:
+ return ShortcutInfo.FLAG_LONG_LIVED;
+ case HAS_ICON_URI:
+ return ShortcutInfo.FLAG_HAS_ICON_URI;
+ case IS_CACHED_NOTIFICATION:
+ return ShortcutInfo.FLAG_CACHED_NOTIFICATIONS;
+ case IS_CACHED_BUBBLE:
+ return ShortcutInfo.FLAG_CACHED_BUBBLES;
+ case IS_CACHED_PEOPLE_TITLE:
+ return ShortcutInfo.FLAG_CACHED_PEOPLE_TILE;
+ default:
+ return 0;
+ }
}
@NonNull
diff --git a/core/java/android/content/pm/DataLoaderParams.java b/core/java/android/content/pm/DataLoaderParams.java
index 93db1e16aea0..f808cfda4835 100644
--- a/core/java/android/content/pm/DataLoaderParams.java
+++ b/core/java/android/content/pm/DataLoaderParams.java
@@ -17,20 +17,24 @@
package android.content.pm;
import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.content.ComponentName;
/**
- * This class represents the parameters used to configure a Data Loader.
+ * This class represents the parameters used to configure a DataLoader.
+ *
+ * {@see android.service.dataloader.DataLoaderService.DataLoader}
*/
public class DataLoaderParams {
@NonNull
private final DataLoaderParamsParcel mData;
/**
- * Creates and populates set of Data Loader parameters for Streaming installation.
+ * Creates and populates set of DataLoader parameters for Streaming installation.
*
- * @param componentName Data Loader component supporting Streaming installation.
- * @param arguments free form installation arguments
+ * @param componentName the component implementing a DataLoaderService that is responsible
+ * for providing data blocks while streaming.
+ * @param arguments free form installation arguments.
*/
public static final @NonNull DataLoaderParams forStreaming(@NonNull ComponentName componentName,
@NonNull String arguments) {
@@ -40,9 +44,12 @@ public class DataLoaderParams {
/**
* Creates and populates set of Data Loader parameters for Incremental installation.
*
- * @param componentName Data Loader component supporting Incremental installation.
+ * @param componentName DataLoaderService component supporting Incremental installation.
* @param arguments free form installation arguments
+ *
+ * @hide
*/
+ @SystemApi
public static final @NonNull DataLoaderParams forIncremental(
@NonNull ComponentName componentName, @NonNull String arguments) {
return new DataLoaderParams(DataLoaderType.INCREMENTAL, componentName, arguments);
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 0be77e01340a..8b380b79e8c7 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -229,8 +229,7 @@ public class PackageInstaller {
/**
* Type of DataLoader for this session. Will be one of
- * {@link #DATA_LOADER_TYPE_NONE}, {@link #DATA_LOADER_TYPE_STREAMING},
- * {@link #DATA_LOADER_TYPE_INCREMENTAL}.
+ * {@link #DATA_LOADER_TYPE_NONE}, {@link #DATA_LOADER_TYPE_STREAMING}.
* <p>
* See the individual types documentation for details.
*
@@ -359,7 +358,9 @@ public class PackageInstaller {
* Streaming installation using Incremental FileSystem.
*
* @see #EXTRA_DATA_LOADER_TYPE
+ * @hide
*/
+ @SystemApi
public static final int DATA_LOADER_TYPE_INCREMENTAL = DataLoaderType.INCREMENTAL;
/**
@@ -1165,7 +1166,7 @@ public class PackageInstaller {
}
/**
- * Adds a file to session. On commit this file will be pulled from dataLoader {@code
+ * Adds a file to session. On commit this file will be pulled from DataLoader {@code
* android.service.dataloader.DataLoaderService.DataLoader}.
*
* @param location target location for the file. Possible values:
@@ -1180,7 +1181,7 @@ public class PackageInstaller {
* @param lengthBytes total size of the file being written.
* The system may clear various caches as needed to allocate
* this space.
- * @param metadata additional info use by dataLoader to pull data for the file.
+ * @param metadata additional info use by DataLoader to pull data for the file.
* @param signature additional file signature, e.g.
* <a href="https://source.android.com/security/apksigning/v4.html">APK Signature Scheme v4</a>
* @throws SecurityException if called after the session has been
@@ -2021,7 +2022,7 @@ public class PackageInstaller {
/**
* Set the data loader params for the session.
- * This also switches installation into data provider mode and disallow direct writes into
+ * This also switches installation into data loading mode and disallow direct writes into
* staging folder.
*
* @see android.service.dataloader.DataLoaderService.DataLoader
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 21de36516751..bba2fd09e712 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2639,8 +2639,12 @@ public abstract class PackageManager {
public static final String FEATURE_SE_OMAPI_SD = "android.hardware.se.omapi.sd";
/**
- * Feature for {@link #getSystemAvailableFeatures} and
- * {@link #hasSystemFeature}: The device is compatible with Android’s security model.
+ * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device is
+ * compatible with Android’s security model.
+ *
+ * <p>See sections 2 and 9 in the
+ * <a href="https://source.android.com/compatibility/android-cdd">Android CDD</a> for more
+ * details.
*/
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_SECURITY_MODEL_COMPATIBLE =
@@ -3497,14 +3501,6 @@ public abstract class PackageManager {
/**
* Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
- * The device supports translation of text-to-text in multiple languages via integration with
- * the system {@link android.service.translation.TranslationService translation provider}.
- */
- @SdkConstant(SdkConstantType.FEATURE)
- public static final String FEATURE_TRANSLATION = "android.software.translation";
-
- /**
- * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
* The device implements headtracking suitable for a VR device.
*/
@SdkConstant(SdkConstantType.FEATURE)
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index 275e81c0e868..76712b5ce2dc 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -148,7 +148,13 @@ public final class ShortcutInfo implements Parcelable {
public static final int FLAG_CACHED_ALL =
FLAG_CACHED_NOTIFICATIONS | FLAG_CACHED_BUBBLES | FLAG_CACHED_PEOPLE_TILE;
- /** @hide */
+ /**
+ * Bitmask-based flags indicating different states associated with the shortcut. Note that if
+ * new value is added here, consider adding also the corresponding string representation and
+ * queries in {@link AppSearchShortcutInfo}.
+ *
+ * @hide
+ */
@IntDef(flag = true, prefix = { "FLAG_" }, value = {
FLAG_DYNAMIC,
FLAG_PINNED,
diff --git a/core/java/android/hardware/face/FaceSensorPropertiesInternal.java b/core/java/android/hardware/face/FaceSensorPropertiesInternal.java
index 44dffb207731..9936b885707e 100644
--- a/core/java/android/hardware/face/FaceSensorPropertiesInternal.java
+++ b/core/java/android/hardware/face/FaceSensorPropertiesInternal.java
@@ -96,6 +96,7 @@ public class FaceSensorPropertiesInternal extends SensorPropertiesInternal {
@Override
public String toString() {
- return "ID: " + sensorId + ", Strength: " + sensorStrength + ", Type: " + sensorType;
+ return "ID: " + sensorId + ", Strength: " + sensorStrength + ", Type: " + sensorType
+ + ", SupportsFaceDetection: " + supportsFaceDetection;
}
}
diff --git a/core/java/android/hardware/fingerprint/IUdfpsHbmListener.aidl b/core/java/android/hardware/fingerprint/IUdfpsHbmListener.aidl
index b79d6e0f9dfe..1551e0742186 100644
--- a/core/java/android/hardware/fingerprint/IUdfpsHbmListener.aidl
+++ b/core/java/android/hardware/fingerprint/IUdfpsHbmListener.aidl
@@ -24,6 +24,13 @@ package android.hardware.fingerprint;
* @hide
*/
oneway interface IUdfpsHbmListener {
+
+ /** HBM that applies to the whole screen. */
+ const int GLOBAL_HBM = 0;
+
+ /** HBM that only applies to a portion of the screen. */
+ const int LOCAL_HBM = 1;
+
/**
* UdfpsController will call this method when the HBM is enabled.
*
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 4743fee3257b..336fbf2954a3 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -22,7 +22,7 @@ import android.hardware.input.KeyboardLayout;
import android.hardware.input.IInputDevicesChangedListener;
import android.hardware.input.ITabletModeChangedListener;
import android.hardware.input.TouchCalibration;
-import android.os.CombinedVibrationEffect;
+import android.os.CombinedVibration;
import android.hardware.input.IInputSensorEventListener;
import android.hardware.input.InputSensorInfo;
import android.hardware.lights.Light;
@@ -91,7 +91,7 @@ interface IInputManager {
// Input device vibrator control.
void vibrate(int deviceId, in VibrationEffect effect, IBinder token);
- void vibrateCombined(int deviceId, in CombinedVibrationEffect effect, IBinder token);
+ void vibrateCombined(int deviceId, in CombinedVibration vibration, IBinder token);
void cancelVibrate(int deviceId, IBinder token);
int[] getVibratorIds(int deviceId);
boolean isVibrating(int deviceId);
diff --git a/core/java/android/hardware/input/InputDeviceVibratorManager.java b/core/java/android/hardware/input/InputDeviceVibratorManager.java
index d843407c289d..ed0efffbb346 100644
--- a/core/java/android/hardware/input/InputDeviceVibratorManager.java
+++ b/core/java/android/hardware/input/InputDeviceVibratorManager.java
@@ -19,7 +19,7 @@ package android.hardware.input;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Binder;
-import android.os.CombinedVibrationEffect;
+import android.os.CombinedVibration;
import android.os.NullVibrator;
import android.os.VibrationAttributes;
import android.os.Vibrator;
@@ -125,7 +125,7 @@ public class InputDeviceVibratorManager extends VibratorManager
}
@Override
- public void vibrate(int uid, String opPkg, @NonNull CombinedVibrationEffect effect,
+ public void vibrate(int uid, String opPkg, @NonNull CombinedVibration effect,
String reason, @Nullable VibrationAttributes attributes) {
mInputManager.vibrate(mDeviceId, effect, mToken);
}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index c83ccfa81f95..b6d2eaf11be6 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -37,7 +37,7 @@ import android.hardware.lights.LightsManager;
import android.hardware.lights.LightsRequest;
import android.os.BlockUntrustedTouchesMode;
import android.os.Build;
-import android.os.CombinedVibrationEffect;
+import android.os.CombinedVibration;
import android.os.Handler;
import android.os.IBinder;
import android.os.IVibratorStateListener;
@@ -1470,7 +1470,7 @@ public final class InputManager {
/*
* Perform combined vibration effect
*/
- void vibrate(int deviceId, CombinedVibrationEffect effect, IBinder token) {
+ void vibrate(int deviceId, CombinedVibration effect, IBinder token) {
try {
mIm.vibrateCombined(deviceId, effect, token);
} catch (RemoteException ex) {
diff --git a/core/java/android/net/IpSecAlgorithm.java b/core/java/android/net/IpSecAlgorithm.java
index 8f1e2defd215..7ef5bac092f6 100644
--- a/core/java/android/net/IpSecAlgorithm.java
+++ b/core/java/android/net/IpSecAlgorithm.java
@@ -354,7 +354,7 @@ public final class IpSecAlgorithm implements Parcelable {
}
for (Entry<String, Integer> entry : ALGO_TO_REQUIRED_FIRST_SDK.entrySet()) {
- if (Build.VERSION.FIRST_SDK_INT >= entry.getValue()) {
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= entry.getValue()) {
enabledAlgos.add(entry.getKey());
}
}
diff --git a/core/java/android/os/BatteryStatsManager.java b/core/java/android/os/BatteryStatsManager.java
index e47478abf439..2c088e233f65 100644
--- a/core/java/android/os/BatteryStatsManager.java
+++ b/core/java/android/os/BatteryStatsManager.java
@@ -429,10 +429,9 @@ public final class BatteryStatsManager {
* @param uid Uid of this event. For the active state it represents the uid that was responsible
* for waking the radio, or -1 if the system was responsible for waking the radio.
* For inactive state, the UID should always be -1.
- * @throws RuntimeException if there are binder remote-invocation errors.
*/
@RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
- public void reportMobileRadioPowerState(boolean isActive, int uid) throws RuntimeException {
+ public void reportMobileRadioPowerState(boolean isActive, int uid) {
try {
mBatteryStats.noteMobileRadioPowerState(getDataConnectionPowerState(isActive),
SystemClock.elapsedRealtimeNanos(), uid);
@@ -448,10 +447,9 @@ public final class BatteryStatsManager {
* @param uid Uid of this event. For the active state it represents the uid that was responsible
* for waking the radio, or -1 if the system was responsible for waking the radio.
* For inactive state, the UID should always be -1.
- * @throws RuntimeException if there are binder remote-invocation errors.
*/
@RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
- public void reportWifiRadioPowerState(boolean isActive, int uid) throws RuntimeException {
+ public void reportWifiRadioPowerState(boolean isActive, int uid) {
try {
mBatteryStats.noteWifiRadioPowerState(getDataConnectionPowerState(isActive),
SystemClock.elapsedRealtimeNanos(), uid);
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 834ae33c14a5..7b8fdd77a250 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -348,7 +348,7 @@ public class Build {
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@TestApi
- public static final int FIRST_SDK_INT = SystemProperties
+ public static final int DEVICE_INITIAL_SDK_INT = SystemProperties
.getInt("ro.product.first_api_level", 0);
/**
diff --git a/core/java/android/os/CombinedVibrationEffect.aidl b/core/java/android/os/CombinedVibration.aidl
index 330733c2643f..91317bde64a3 100644
--- a/core/java/android/os/CombinedVibrationEffect.aidl
+++ b/core/java/android/os/CombinedVibration.aidl
@@ -16,4 +16,4 @@
package android.os;
-parcelable CombinedVibrationEffect;
+parcelable CombinedVibration;
diff --git a/core/java/android/os/CombinedVibrationEffect.java b/core/java/android/os/CombinedVibration.java
index e068772e954a..aff55aff39f7 100644
--- a/core/java/android/os/CombinedVibrationEffect.java
+++ b/core/java/android/os/CombinedVibration.java
@@ -27,56 +27,61 @@ import java.util.List;
import java.util.Objects;
/**
- * A CombinedVibrationEffect describes a haptic effect to be performed by one or more {@link
- * Vibrator Vibrators}.
+ * A CombinedVibration describes a combination of haptic effects to be performed by one or more
+ * {@link Vibrator Vibrators}.
*
* These effects may be any number of things, from single shot vibrations to complex waveforms.
+ *
* @see VibrationEffect
*/
@SuppressWarnings({"ParcelNotFinal", "ParcelCreator"}) // Parcel only extended here.
-public abstract class CombinedVibrationEffect implements Parcelable {
+public abstract class CombinedVibration implements Parcelable {
private static final int PARCEL_TOKEN_MONO = 1;
private static final int PARCEL_TOKEN_STEREO = 2;
private static final int PARCEL_TOKEN_SEQUENTIAL = 3;
/** Prevent subclassing from outside of the framework. */
- CombinedVibrationEffect() {
+ CombinedVibration() {
}
/**
- * Create a synced vibration effect.
+ * Create a vibration that plays a single effect in parallel on all vibrators.
*
- * A synced vibration effect should be performed by multiple vibrators at the same time.
+ * A parallel vibration that takes a single {@link VibrationEffect} to be performed by multiple
+ * vibrators at the same time.
*
* @param effect The {@link VibrationEffect} to perform.
- * @return The synced effect.
+ * @return The combined vibration representing the single effect to be played in all vibrators.
*/
@NonNull
- public static CombinedVibrationEffect createSynced(@NonNull VibrationEffect effect) {
- CombinedVibrationEffect combined = new Mono(effect);
+ public static CombinedVibration createParallel(@NonNull VibrationEffect effect) {
+ CombinedVibration combined = new Mono(effect);
combined.validate();
return combined;
}
/**
- * Start creating a synced vibration effect.
+ * Start creating a vibration that plays effects in parallel on one or more vibrators.
*
- * A synced vibration effect should be performed by multiple vibrators at the same time.
+ * A parallel vibration takes one or more {@link VibrationEffect VibrationEffects} associated to
+ * individual vibrators to be performed at the same time.
*
- * @see CombinedVibrationEffect.SyncedCombination
+ * @see CombinedVibration.ParallelCombination
*/
@NonNull
- public static SyncedCombination startSynced() {
- return new SyncedCombination();
+ public static ParallelCombination startParallel() {
+ return new ParallelCombination();
}
/**
- * Start creating a sequential vibration effect.
+ * Start creating a vibration that plays effects in sequence on one or more vibrators.
*
- * A sequential vibration effect should be performed by multiple vibrators in order.
+ * A sequential vibration takes one or more {@link CombinedVibration CombinedVibrations} to be
+ * performed by one or more vibrators in order. Each {@link CombinedVibration} starts only after
+ * the previous one is finished.
*
- * @see CombinedVibrationEffect.SequentialCombination
* @hide
+ * @see CombinedVibration.SequentialCombination
*/
@TestApi
@NonNull
@@ -92,7 +97,7 @@ public abstract class CombinedVibrationEffect implements Parcelable {
/**
* Gets the estimated duration of the combined vibration in milliseconds.
*
- * <p>For synced combinations this means the maximum duration of any individual {@link
+ * <p>For parallel combinations this means the maximum duration of any individual {@link
* VibrationEffect}. For sequential combinations, this is a sum of each step and delays.
*
* <p>For combinations of effects without a defined end (e.g. a Waveform with a non-negative
@@ -112,15 +117,15 @@ public abstract class CombinedVibrationEffect implements Parcelable {
public abstract boolean hasVibrator(int vibratorId);
/**
- * A combination of haptic effects that should be played in multiple vibrators in sync.
+ * A combination of haptic effects that should be played in multiple vibrators in parallel.
*
- * @see CombinedVibrationEffect#startSynced()
+ * @see CombinedVibration#startParallel()
*/
- public static final class SyncedCombination {
+ public static final class ParallelCombination {
private final SparseArray<VibrationEffect> mEffects = new SparseArray<>();
- SyncedCombination() {
+ ParallelCombination() {
}
/**
@@ -128,33 +133,33 @@ public abstract class CombinedVibrationEffect implements Parcelable {
*
* @param vibratorId The id of the vibrator that should perform this effect.
* @param effect The effect this vibrator should play.
- * @return The {@link CombinedVibrationEffect.SyncedCombination} object to enable adding
+ * @return The {@link ParallelCombination} object to enable adding
* multiple effects in one chain.
* @see VibrationEffect#createOneShot(long, int)
*/
@NonNull
- public SyncedCombination addVibrator(int vibratorId, @NonNull VibrationEffect effect) {
+ public ParallelCombination addVibrator(int vibratorId, @NonNull VibrationEffect effect) {
mEffects.put(vibratorId, effect);
return this;
}
/**
- * Combine all of the added effects into a combined effect.
+ * Combine all of the added effects into a {@link CombinedVibration}.
*
- * The {@link CombinedVibrationEffect.SyncedCombination} object is still valid after this
+ * The {@link ParallelCombination} object is still valid after this
* call, so you can continue adding more effects to it and generating more
- * {@link CombinedVibrationEffect}s by calling this method again.
+ * {@link CombinedVibration}s by calling this method again.
*
- * @return The {@link CombinedVibrationEffect} resulting from combining the added effects to
- * be played in sync.
+ * @return The {@link CombinedVibration} resulting from combining the added effects to
+ * be played in parallel.
*/
@NonNull
- public CombinedVibrationEffect combine() {
+ public CombinedVibration combine() {
if (mEffects.size() == 0) {
throw new IllegalStateException(
"Combination must have at least one element to combine.");
}
- CombinedVibrationEffect combined = new Stereo(mEffects);
+ CombinedVibration combined = new Stereo(mEffects);
combined.validate();
return combined;
}
@@ -163,13 +168,13 @@ public abstract class CombinedVibrationEffect implements Parcelable {
/**
* A combination of haptic effects that should be played in multiple vibrators in sequence.
*
- * @see CombinedVibrationEffect#startSequential()
* @hide
+ * @see CombinedVibration#startSequential()
*/
@TestApi
public static final class SequentialCombination {
- private final ArrayList<CombinedVibrationEffect> mEffects = new ArrayList<>();
+ private final ArrayList<CombinedVibration> mEffects = new ArrayList<>();
private final ArrayList<Integer> mDelays = new ArrayList<>();
SequentialCombination() {
@@ -178,11 +183,12 @@ public abstract class CombinedVibrationEffect implements Parcelable {
/**
* Add a single vibration effect to be performed next.
*
- * Similar to {@link #addNext(int, VibrationEffect, int)}, but with no delay.
+ * Similar to {@link #addNext(int, VibrationEffect, int)}, but with no delay. The effect
+ * will start playing immediately after the previous vibration is finished.
*
* @param vibratorId The id of the vibrator that should perform this effect.
* @param effect The effect this vibrator should play.
- * @return The {@link CombinedVibrationEffect.SequentialCombination} object to enable adding
+ * @return The {@link CombinedVibration.SequentialCombination} object to enable adding
* multiple effects in one chain.
*/
@NonNull
@@ -193,47 +199,56 @@ public abstract class CombinedVibrationEffect implements Parcelable {
/**
* Add a single vibration effect to be performed next.
*
+ * The delay is applied immediately after the previous vibration is finished. The effect
+ * will start playing after the delay.
+ *
* @param vibratorId The id of the vibrator that should perform this effect.
* @param effect The effect this vibrator should play.
* @param delay The amount of time, in milliseconds, to wait between playing the prior
- * effect and this one.
- * @return The {@link CombinedVibrationEffect.SequentialCombination} object to enable adding
+ * vibration and this one, starting at the time the previous vibration in
+ * this sequence is finished.
+ * @return The {@link CombinedVibration.SequentialCombination} object to enable adding
* multiple effects in one chain.
*/
@NonNull
public SequentialCombination addNext(int vibratorId, @NonNull VibrationEffect effect,
int delay) {
return addNext(
- CombinedVibrationEffect.startSynced().addVibrator(vibratorId, effect).combine(),
+ CombinedVibration.startParallel().addVibrator(vibratorId, effect).combine(),
delay);
}
/**
* Add a combined vibration effect to be performed next.
*
- * Similar to {@link #addNext(CombinedVibrationEffect, int)}, but with no delay.
+ * Similar to {@link #addNext(CombinedVibration, int)}, but with no delay. The effect will
+ * start playing immediately after the previous vibration is finished.
*
* @param effect The combined effect to be performed next.
- * @return The {@link CombinedVibrationEffect.SequentialCombination} object to enable adding
+ * @return The {@link CombinedVibration.SequentialCombination} object to enable adding
* multiple effects in one chain.
* @see VibrationEffect#createOneShot(long, int)
*/
@NonNull
- public SequentialCombination addNext(@NonNull CombinedVibrationEffect effect) {
+ public SequentialCombination addNext(@NonNull CombinedVibration effect) {
return addNext(effect, /* delay= */ 0);
}
/**
- * Add a one shot vibration effect to be performed by the specified vibrator.
+ * Add a combined vibration effect to be performed next.
+ *
+ * The delay is applied immediately after the previous vibration is finished. The vibration
+ * will start playing after the delay.
*
* @param effect The combined effect to be performed next.
* @param delay The amount of time, in milliseconds, to wait between playing the prior
- * effect and this one.
- * @return The {@link CombinedVibrationEffect.SequentialCombination} object to enable adding
+ * vibration and this one, starting at the time the previous vibration in this
+ * sequence is finished.
+ * @return The {@link CombinedVibration.SequentialCombination} object to enable adding
* multiple effects in one chain.
*/
@NonNull
- public SequentialCombination addNext(@NonNull CombinedVibrationEffect effect, int delay) {
+ public SequentialCombination addNext(@NonNull CombinedVibration effect, int delay) {
if (effect instanceof Sequential) {
Sequential sequentialEffect = (Sequential) effect;
int firstEffectIndex = mDelays.size();
@@ -250,32 +265,33 @@ public abstract class CombinedVibrationEffect implements Parcelable {
/**
* Combine all of the added effects in sequence.
*
- * The {@link CombinedVibrationEffect.SequentialCombination} object is still valid after
+ * The {@link CombinedVibration.SequentialCombination} object is still valid after
* this call, so you can continue adding more effects to it and generating more {@link
- * CombinedVibrationEffect}s by calling this method again.
+ * CombinedVibration}s by calling this method again.
*
- * @return The {@link CombinedVibrationEffect} resulting from combining the added effects to
+ * @return The {@link CombinedVibration} resulting from combining the added effects to
* be played in sequence.
*/
@NonNull
- public CombinedVibrationEffect combine() {
+ public CombinedVibration combine() {
if (mEffects.size() == 0) {
throw new IllegalStateException(
"Combination must have at least one element to combine.");
}
- CombinedVibrationEffect combined = new Sequential(mEffects, mDelays);
+ CombinedVibration combined = new Sequential(mEffects, mDelays);
combined.validate();
return combined;
}
}
/**
- * Represents a single {@link VibrationEffect} that should be executed in all vibrators in sync.
+ * Represents a single {@link VibrationEffect} that should be played in all vibrators at the
+ * same time.
*
* @hide
*/
@TestApi
- public static final class Mono extends CombinedVibrationEffect {
+ public static final class Mono extends CombinedVibration {
private final VibrationEffect mEffect;
Mono(Parcel in) {
@@ -357,12 +373,13 @@ public abstract class CombinedVibrationEffect implements Parcelable {
}
/**
- * Represents a list of {@link VibrationEffect}s that should be executed in sync.
+ * Represents a set of {@link VibrationEffect VibrationEffects} associated to individual
+ * vibrators that should be played at the same time.
*
* @hide
*/
@TestApi
- public static final class Stereo extends CombinedVibrationEffect {
+ public static final class Stereo extends CombinedVibration {
/** Mapping vibrator ids to effects. */
private final SparseArray<VibrationEffect> mEffects;
@@ -383,7 +400,7 @@ public abstract class CombinedVibrationEffect implements Parcelable {
}
}
- /** Effects to be performed in sync, where each key represents the vibrator id. */
+ /** Effects to be performed in parallel, where each key represents the vibrator id. */
@NonNull
public SparseArray<VibrationEffect> getEffects() {
return mEffects;
@@ -489,13 +506,14 @@ public abstract class CombinedVibrationEffect implements Parcelable {
}
/**
- * Represents a list of {@link VibrationEffect}s that should be executed in sequence.
+ * Represents a list of {@link CombinedVibration CombinedVibrations} that should be played in
+ * sequence.
*
* @hide
*/
@TestApi
- public static final class Sequential extends CombinedVibrationEffect {
- private final List<CombinedVibrationEffect> mEffects;
+ public static final class Sequential extends CombinedVibration {
+ private final List<CombinedVibration> mEffects;
private final List<Integer> mDelays;
Sequential(Parcel in) {
@@ -504,11 +522,11 @@ public abstract class CombinedVibrationEffect implements Parcelable {
mDelays = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
mDelays.add(in.readInt());
- mEffects.add(CombinedVibrationEffect.CREATOR.createFromParcel(in));
+ mEffects.add(CombinedVibration.CREATOR.createFromParcel(in));
}
}
- Sequential(@NonNull List<CombinedVibrationEffect> effects,
+ Sequential(@NonNull List<CombinedVibration> effects,
@NonNull List<Integer> delays) {
mEffects = new ArrayList<>(effects);
mDelays = new ArrayList<>(delays);
@@ -516,7 +534,7 @@ public abstract class CombinedVibrationEffect implements Parcelable {
/** Effects to be performed in sequence. */
@NonNull
- public List<CombinedVibrationEffect> getEffects() {
+ public List<CombinedVibration> getEffects() {
return mEffects;
}
@@ -532,7 +550,7 @@ public abstract class CombinedVibrationEffect implements Parcelable {
long durations = 0;
final int effectCount = mEffects.size();
for (int i = 0; i < effectCount; i++) {
- CombinedVibrationEffect effect = mEffects.get(i);
+ CombinedVibration effect = mEffects.get(i);
long duration = effect.getDuration();
if (duration == Long.MAX_VALUE) {
// If any duration is repeating, this combination duration is also repeating.
@@ -570,7 +588,7 @@ public abstract class CombinedVibrationEffect implements Parcelable {
}
}
for (int i = 0; i < effectCount; i++) {
- CombinedVibrationEffect effect = mEffects.get(i);
+ CombinedVibration effect = mEffects.get(i);
if (effect instanceof Sequential) {
throw new IllegalArgumentException(
"There should be no nested sequential effects in a combined effect");
@@ -644,10 +662,10 @@ public abstract class CombinedVibrationEffect implements Parcelable {
}
@NonNull
- public static final Parcelable.Creator<CombinedVibrationEffect> CREATOR =
- new Parcelable.Creator<CombinedVibrationEffect>() {
+ public static final Parcelable.Creator<CombinedVibration> CREATOR =
+ new Parcelable.Creator<CombinedVibration>() {
@Override
- public CombinedVibrationEffect createFromParcel(Parcel in) {
+ public CombinedVibration createFromParcel(Parcel in) {
int token = in.readInt();
if (token == PARCEL_TOKEN_MONO) {
return new Mono(in);
@@ -662,8 +680,8 @@ public abstract class CombinedVibrationEffect implements Parcelable {
}
@Override
- public CombinedVibrationEffect[] newArray(int size) {
- return new CombinedVibrationEffect[size];
+ public CombinedVibration[] newArray(int size) {
+ return new CombinedVibration[size];
}
};
}
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 40c658f01e28..a06a8577a56a 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -22,6 +22,8 @@ import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
import static android.os.ParcelFileDescriptor.MODE_TRUNCATE;
import static android.os.ParcelFileDescriptor.MODE_WRITE_ONLY;
+import static android.system.OsConstants.EINVAL;
+import static android.system.OsConstants.ENOSYS;
import static android.system.OsConstants.F_OK;
import static android.system.OsConstants.O_ACCMODE;
import static android.system.OsConstants.O_APPEND;
@@ -441,7 +443,19 @@ public final class FileUtils {
final StructStat st_in = Os.fstat(in);
final StructStat st_out = Os.fstat(out);
if (S_ISREG(st_in.st_mode) && S_ISREG(st_out.st_mode)) {
- return copyInternalSendfile(in, out, count, signal, executor, listener);
+ try {
+ return copyInternalSendfile(in, out, count, signal, executor, listener);
+ } catch (ErrnoException e) {
+ if (e.errno == EINVAL || e.errno == ENOSYS) {
+ // sendfile(2) will fail in at least any of the following conditions:
+ // 1. |in| doesn't support mmap(2)
+ // 2. |out| was opened with O_APPEND
+ // We fallback to userspace copy if that fails
+ return copyInternalUserspace(in, out, count, signal, executor,
+ listener);
+ }
+ throw e;
+ }
} else if (S_ISFIFO(st_in.st_mode) || S_ISFIFO(st_out.st_mode)) {
return copyInternalSplice(in, out, count, signal, executor, listener);
}
diff --git a/core/java/android/os/IHintManager.aidl b/core/java/android/os/IHintManager.aidl
new file mode 100644
index 000000000000..661b95affaf3
--- /dev/null
+++ b/core/java/android/os/IHintManager.aidl
@@ -0,0 +1,33 @@
+/*
+ *
+ * Copyright 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.os;
+
+import android.os.IHintSession;
+
+/** {@hide} */
+interface IHintManager {
+ /**
+ * Creates a {@link Session} for the given set of threads and associates to a binder token.
+ */
+ IHintSession createHintSession(in IBinder token, in int[] tids, long durationNanos);
+
+ /**
+ * Get preferred rate limit in nano second.
+ */
+ long getHintSessionPreferredRate();
+}
diff --git a/core/java/android/os/IHintSession.aidl b/core/java/android/os/IHintSession.aidl
new file mode 100644
index 000000000000..09bc4cc4eb7e
--- /dev/null
+++ b/core/java/android/os/IHintSession.aidl
@@ -0,0 +1,25 @@
+/*
+ *
+ * Copyright 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.os;
+
+/** {@hide} */
+oneway interface IHintSession {
+ void updateTargetWorkDuration(long targetDurationNanos);
+ void reportActualWorkDuration(in long[] actualDurationNanos, in long[] timeStampNanos);
+ void close();
+}
diff --git a/core/java/android/os/IVibratorManagerService.aidl b/core/java/android/os/IVibratorManagerService.aidl
index f9e294791cca..c58cc4f9988f 100644
--- a/core/java/android/os/IVibratorManagerService.aidl
+++ b/core/java/android/os/IVibratorManagerService.aidl
@@ -16,7 +16,7 @@
package android.os;
-import android.os.CombinedVibrationEffect;
+import android.os.CombinedVibration;
import android.os.IVibratorStateListener;
import android.os.VibrationAttributes;
import android.os.VibratorInfo;
@@ -29,8 +29,8 @@ interface IVibratorManagerService {
boolean registerVibratorStateListener(int vibratorId, in IVibratorStateListener listener);
boolean unregisterVibratorStateListener(int vibratorId, in IVibratorStateListener listener);
boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId,
- in CombinedVibrationEffect effect, in VibrationAttributes attributes);
- void vibrate(int uid, String opPkg, in CombinedVibrationEffect effect,
+ in CombinedVibration vibration, in VibrationAttributes attributes);
+ void vibrate(int uid, String opPkg, in CombinedVibration vibration,
in VibrationAttributes attributes, String reason, IBinder token);
void cancelVibrate(IBinder token);
}
diff --git a/core/java/android/os/PerformanceHintManager.java b/core/java/android/os/PerformanceHintManager.java
new file mode 100644
index 000000000000..6791844a2a00
--- /dev/null
+++ b/core/java/android/os/PerformanceHintManager.java
@@ -0,0 +1,226 @@
+/*
+ * 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.os;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemService;
+import android.content.Context;
+
+import com.android.internal.util.Preconditions;
+
+import java.io.Closeable;
+import java.util.ArrayList;
+
+/** The PerformanceHintManager allows apps to send performance hint to system. */
+@SystemService(Context.PERFORMANCE_HINT_SERVICE)
+public final class PerformanceHintManager {
+ private static final String TAG = "PerformanceHintManager";
+ private final IHintManager mService;
+ // HAL preferred update rate
+ private final long mPreferredRate;
+
+ /** @hide */
+ public PerformanceHintManager(IHintManager service) {
+ mService = service;
+ try {
+ mPreferredRate = mService.getHintSessionPreferredRate();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Creates a {@link Session} for the given set of threads and sets their initial target work
+ * duration.
+ *
+ * @param tids The list of threads to be associated with this session. They must be part of
+ * this process' thread group.
+ * @param initialTargetWorkDurationNanos The desired duration in nanoseconds for the new
+ * session.
+ * @return the new session if it is supported on this device, null if hint session is not
+ * supported on this device.
+ */
+ @Nullable
+ public Session createHintSession(@NonNull int[] tids, long initialTargetWorkDurationNanos) {
+ try {
+ IBinder token = new Binder();
+ IHintSession session = mService.createHintSession(token, tids,
+ initialTargetWorkDurationNanos);
+ if (session == null) return null;
+ return new Session(session, sNanoClock, mPreferredRate,
+ initialTargetWorkDurationNanos);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Get preferred update rate information for this device.
+ *
+ * @return the preferred update rate supported by device software.
+ */
+ public long getPreferredUpdateRateNanos() {
+ return mPreferredRate;
+ }
+
+ /**
+ * A Session represents a group of threads with an inter-related workload such that hints for
+ * their performance should be considered as a unit. The threads in a given session should be
+ * long-life and not created or destroyed dynamically.
+ *
+ * <p>Each session is expected to have a periodic workload with a target duration for each
+ * cycle. The cycle duration is likely greater than the target work duration to allow other
+ * parts of the pipeline to run within the available budget. For example, a renderer thread may
+ * work at 60hz in order to produce frames at the display's frame but have a target work
+ * duration of only 6ms.</p>
+ *
+ * <p>Any call in this class will change its internal data, so you must do your own thread
+ * safety to protect from racing.</p>
+ *
+ * <p>Note that the target work duration can be {@link #updateTargetWorkDuration(long) updated}
+ * if workloads change.</p>
+ *
+ * <p>After each cycle of work, the client is expected to
+ * {@link #reportActualWorkDuration(long) report} the actual time taken to complete.</p>
+ *
+ * <p>All timings should be in {@link SystemClock#elapsedRealtimeNanos()}.</p>
+ */
+ public static class Session implements Closeable {
+ private final IHintSession mSession;
+ private final NanoClock mElapsedRealtimeClock;
+ // Target duration for choosing update rate
+ private long mTargetDurationInNanos;
+ // HAL preferred update rate
+ private long mPreferredRate;
+ // Last update timestamp
+ private long mLastUpdateTimeStamp = -1L;
+ // Cached samples
+ private final ArrayList<Long> mActualDurationNanos;
+ private final ArrayList<Long> mTimeStampNanos;
+
+ /** @hide */
+ public Session(IHintSession session, NanoClock elapsedRealtimeClock, long preferredRate,
+ long durationNanos) {
+ mSession = session;
+ mElapsedRealtimeClock = elapsedRealtimeClock;
+ mTargetDurationInNanos = durationNanos;
+ mPreferredRate = preferredRate;
+ mActualDurationNanos = new ArrayList<Long>();
+ mTimeStampNanos = new ArrayList<Long>();
+ mLastUpdateTimeStamp = mElapsedRealtimeClock.nanos();
+ }
+
+ /**
+ * Updates this session's target duration for each cycle of work.
+ *
+ * @param targetDurationNanos the new desired duration in nanoseconds
+ */
+ public void updateTargetWorkDuration(long targetDurationNanos) {
+ Preconditions.checkArgumentPositive(targetDurationNanos, "the hint target duration"
+ + " should be positive.");
+ try {
+ mSession.updateTargetWorkDuration(targetDurationNanos);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ mTargetDurationInNanos = targetDurationNanos;
+ /**
+ * Most of the workload is target_duration dependent, so now clear the cached samples
+ * as they are most likely obsolete.
+ */
+ mActualDurationNanos.clear();
+ mTimeStampNanos.clear();
+ mLastUpdateTimeStamp = mElapsedRealtimeClock.nanos();
+ }
+
+ /**
+ * Reports the actual duration for the last cycle of work.
+ *
+ * <p>The system will attempt to adjust the core placement of the threads within the thread
+ * group and/or the frequency of the core on which they are run to bring the actual duration
+ * close to the target duration.</p>
+ *
+ * @param actualDurationNanos how long the thread group took to complete its last task in
+ * nanoseconds
+ */
+ public void reportActualWorkDuration(long actualDurationNanos) {
+ Preconditions.checkArgumentPositive(actualDurationNanos, "the actual duration should"
+ + " be positive.");
+ final long now = mElapsedRealtimeClock.nanos();
+ mActualDurationNanos.add(actualDurationNanos);
+ mTimeStampNanos.add(now);
+
+ /**
+ * Use current sample to determine the rate limit. We can pick a shorter rate limit
+ * if any sample underperformed, however, it could be the lower level system is slow
+ * to react. So here we explicitly choose the rate limit with the latest sample.
+ */
+ long rateLimit =
+ actualDurationNanos > mTargetDurationInNanos ? mPreferredRate
+ : 10 * mPreferredRate;
+
+ if (now - mLastUpdateTimeStamp <= rateLimit) {
+ return;
+ }
+ Preconditions.checkState(mActualDurationNanos.size() == mTimeStampNanos.size());
+ final int size = mActualDurationNanos.size();
+ long[] actualDurationArray = new long[size];
+ long[] timeStampArray = new long[size];
+ for (int i = 0; i < size; i++) {
+ actualDurationArray[i] = mActualDurationNanos.get(i);
+ timeStampArray[i] = mTimeStampNanos.get(i);
+ }
+ try {
+ mSession.reportActualWorkDuration(actualDurationArray, timeStampArray);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ mActualDurationNanos.clear();
+ mTimeStampNanos.clear();
+ mLastUpdateTimeStamp = now;
+ }
+
+ /**
+ * Ends the current hint session.
+ *
+ * <p>Once called, you should not call anything else on this object.</p>
+ */
+ public void close() {
+ try {
+ mSession.close();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * The interface is to make the FakeClock for testing.
+ * @hide
+ */
+ public interface NanoClock {
+ /** Gets the current nanosecond instant of the clock. */
+ long nanos();
+ }
+
+ private static final NanoClock sNanoClock = new NanoClock() {
+ public long nanos() {
+ return SystemClock.elapsedRealtimeNanos();
+ }
+ };
+}
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index 219912c24e70..2e8ecb59b0d3 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -168,7 +168,7 @@ public class SystemVibrator extends Vibrator {
return false;
}
VibrationAttributes attr = new VibrationAttributes.Builder(attributes, effect).build();
- CombinedVibrationEffect combinedEffect = CombinedVibrationEffect.createSynced(effect);
+ CombinedVibration combinedEffect = CombinedVibration.createParallel(effect);
return mVibratorManager.setAlwaysOnEffect(uid, opPkg, alwaysOnId, combinedEffect, attr);
}
@@ -179,7 +179,7 @@ public class SystemVibrator extends Vibrator {
Log.w(TAG, "Failed to vibrate; no vibrator manager.");
return;
}
- CombinedVibrationEffect combinedEffect = CombinedVibrationEffect.createSynced(effect);
+ CombinedVibration combinedEffect = CombinedVibration.createParallel(effect);
mVibratorManager.vibrate(uid, opPkg, combinedEffect, reason, attributes);
}
diff --git a/core/java/android/os/SystemVibratorManager.java b/core/java/android/os/SystemVibratorManager.java
index 5d8190213119..84a1016e3364 100644
--- a/core/java/android/os/SystemVibratorManager.java
+++ b/core/java/android/os/SystemVibratorManager.java
@@ -117,7 +117,7 @@ public class SystemVibratorManager extends VibratorManager {
@Override
public boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId,
- @Nullable CombinedVibrationEffect effect, @Nullable VibrationAttributes attributes) {
+ @Nullable CombinedVibration effect, @Nullable VibrationAttributes attributes) {
if (mService == null) {
Log.w(TAG, "Failed to set always-on effect; no vibrator manager service.");
return false;
@@ -131,7 +131,7 @@ public class SystemVibratorManager extends VibratorManager {
}
@Override
- public void vibrate(int uid, String opPkg, @NonNull CombinedVibrationEffect effect,
+ public void vibrate(int uid, String opPkg, @NonNull CombinedVibration effect,
String reason, @Nullable VibrationAttributes attributes) {
if (mService == null) {
Log.w(TAG, "Failed to vibrate; no vibrator manager service.");
@@ -240,7 +240,7 @@ public class SystemVibratorManager extends VibratorManager {
try {
VibrationAttributes attr = new VibrationAttributes.Builder(
attributes, effect).build();
- CombinedVibrationEffect combined = CombinedVibrationEffect.startSynced()
+ CombinedVibration combined = CombinedVibration.startParallel()
.addVibrator(mVibratorInfo.getId(), effect)
.combine();
return mService.setAlwaysOnEffect(uid, opPkg, alwaysOnId, combined, attr);
@@ -259,7 +259,7 @@ public class SystemVibratorManager extends VibratorManager {
return;
}
try {
- CombinedVibrationEffect combined = CombinedVibrationEffect.startSynced()
+ CombinedVibration combined = CombinedVibration.startParallel()
.addVibrator(mVibratorInfo.getId(), vibe)
.combine();
mService.vibrate(uid, opPkg, combined, attributes, reason, mToken);
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 2119e7b951cd..4a6216e9046a 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -326,16 +326,15 @@ public final class UserHandle implements Parcelable {
}
/**
- * Returns the uid that is composed from the userHandle and the appId.
+ * Returns the uid representing the given appId for this UserHandle.
*
- * @param userHandle the UserHandle to compose the uid
* @param appId the AppId to compose the uid
- * @return the uid that is composed from the userHandle and the appId
+ * @return the uid representing the given appId for this UserHandle
* @hide
*/
@SystemApi
- public static int getUid(@NonNull UserHandle userHandle, @AppIdInt int appId) {
- return getUid(userHandle.getIdentifier(), appId);
+ public int getUid(@AppIdInt int appId) {
+ return getUid(getIdentifier(), appId);
}
/**
diff --git a/core/java/android/os/VibratorManager.java b/core/java/android/os/VibratorManager.java
index 5a01814508e1..7c911160dfa6 100644
--- a/core/java/android/os/VibratorManager.java
+++ b/core/java/android/os/VibratorManager.java
@@ -69,7 +69,7 @@ public abstract class VibratorManager {
public abstract Vibrator getVibrator(int vibratorId);
/**
- * Returns the system default Vibrator service.
+ * Returns the default Vibrator for the device.
*/
@NonNull
public abstract Vibrator getDefaultVibrator();
@@ -81,7 +81,7 @@ public abstract class VibratorManager {
*/
@RequiresPermission(android.Manifest.permission.VIBRATE_ALWAYS_ON)
public boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId,
- @Nullable CombinedVibrationEffect effect, @Nullable VibrationAttributes attributes) {
+ @Nullable CombinedVibration effect, @Nullable VibrationAttributes attributes) {
Log.w(TAG, "Always-on effects aren't supported");
return false;
}
@@ -90,14 +90,14 @@ public abstract class VibratorManager {
* Vibrate with a given combination of effects.
*
* <p>
- * Pass in a {@link CombinedVibrationEffect} representing a combination of {@link
+ * Pass in a {@link CombinedVibration} representing a combination of {@link
* VibrationEffect VibrationEffects} to be played on one or more vibrators.
* </p>
*
* @param effect a combination of effects to be performed by one or more vibrators.
*/
@RequiresPermission(android.Manifest.permission.VIBRATE)
- public final void vibrate(@NonNull CombinedVibrationEffect effect) {
+ public final void vibrate(@NonNull CombinedVibration effect) {
vibrate(effect, null);
}
@@ -105,7 +105,7 @@ public abstract class VibratorManager {
* Vibrate with a given combination of effects.
*
* <p>
- * Pass in a {@link CombinedVibrationEffect} representing a combination of {@link
+ * Pass in a {@link CombinedVibration} representing a combination of {@link
* VibrationEffect} to be played on one or more vibrators.
* </p>
*
@@ -116,19 +116,19 @@ public abstract class VibratorManager {
* incoming calls.
*/
@RequiresPermission(android.Manifest.permission.VIBRATE)
- public final void vibrate(@NonNull CombinedVibrationEffect effect,
+ public final void vibrate(@NonNull CombinedVibration effect,
@Nullable VibrationAttributes attributes) {
vibrate(Process.myUid(), mPackageName, effect, null, attributes);
}
/**
- * Like {@link #vibrate(CombinedVibrationEffect, VibrationAttributes)}, but allows the
+ * Like {@link #vibrate(CombinedVibration, VibrationAttributes)}, but allows the
* caller to specify the vibration is owned by someone else and set reason for vibration.
*
* @hide
*/
@RequiresPermission(android.Manifest.permission.VIBRATE)
- public abstract void vibrate(int uid, String opPkg, @NonNull CombinedVibrationEffect effect,
+ public abstract void vibrate(int uid, String opPkg, @NonNull CombinedVibration effect,
String reason, @Nullable VibrationAttributes attributes);
/**
diff --git a/core/java/android/permission/AdminPermissionControlParams.java b/core/java/android/permission/AdminPermissionControlParams.java
index 49507220e7b0..3eeaa5f4fe0a 100644
--- a/core/java/android/permission/AdminPermissionControlParams.java
+++ b/core/java/android/permission/AdminPermissionControlParams.java
@@ -56,7 +56,8 @@ public final class AdminPermissionControlParams implements Parcelable {
*/
public AdminPermissionControlParams(@NonNull String granteePackageName,
@NonNull String permission,
- int grantState, boolean canAdminGrantSensorsPermissions) {
+ @DevicePolicyManager.PermissionGrantState int grantState,
+ boolean canAdminGrantSensorsPermissions) {
Preconditions.checkStringNotEmpty(granteePackageName, "Package name must not be empty.");
Preconditions.checkStringNotEmpty(permission, "Permission must not be empty.");
checkArgument(grantState == PERMISSION_GRANT_STATE_GRANTED
@@ -112,7 +113,7 @@ public final class AdminPermissionControlParams implements Parcelable {
}
/** Returns the grant state */
- public int getGrantState() {
+ public @DevicePolicyManager.PermissionGrantState int getGrantState() {
return mGrantState;
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f3c37ff827af..9450994af89f 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8539,13 +8539,16 @@ public final class Settings {
"one_handed_tutorial_show_count";
/**
- * Indicates whether transform is enabled.
+ * Indicates whether ui translation is enabled.
* <p>
* Type: int (0 for false, 1 for true)
*
* @hide
*/
- public static final String TRANSFORM_ENABLED = "transform_enabled";
+ @SystemApi
+ @Readable
+ @SuppressLint("NoSettingsProvider")
+ public static final String UI_TRANSLATION_ENABLED = "ui_translation_enabled";
/**
* The current night mode that has been selected by the user. Owned
@@ -9929,6 +9932,14 @@ public final class Settings {
"clipboard_show_access_notifications";
/**
+ * If nonzero, nas has not been updated to reflect new changes.
+ * @hide
+ */
+ @Readable
+ public static final String NAS_SETTINGS_UPDATED = "nas_settings_updated";
+
+
+ /**
* These entries are considered common between the personal and the managed profile,
* since the managed profile doesn't get to change them.
*/
@@ -13319,23 +13330,27 @@ public final class Settings {
"adb_allowed_connection_time";
/**
- * Scaling factor for normal window animations. Setting to 0 will
- * disable window animations.
+ * Scaling factor for normal window animations.
+ *
+ * The value is a float. Setting to 0.0f will disable window animations.
*/
@Readable
public static final String WINDOW_ANIMATION_SCALE = "window_animation_scale";
/**
- * Scaling factor for activity transition animations. Setting to 0 will
- * disable window animations.
+ * Scaling factor for activity transition animations.
+ *
+ * The value is a float. Setting to 0.0f will disable window animations.
*/
@Readable
public static final String TRANSITION_ANIMATION_SCALE = "transition_animation_scale";
/**
* Scaling factor for Animator-based animations. This affects both the
- * start delay and duration of all such animations. Setting to 0 will
- * cause animations to end immediately. The default value is 1.
+ * start delay and duration of all such animations.
+ *
+ * The value is a float. Setting to 0.0f will cause animations to end immediately.
+ * The default value is 1.0f.
*/
@Readable
public static final String ANIMATOR_DURATION_SCALE = "animator_duration_scale";
@@ -14712,6 +14727,15 @@ public final class Settings {
public static final String POWER_BUTTON_VERY_LONG_PRESS =
"power_button_very_long_press";
+ /**
+ * Overrides internal R.integer.config_keyChordPowerVolumeUp.
+ * Allowable values detailed in frameworks/base/core/res/res/values/config.xml.
+ * Used by PhoneWindowManager.
+ * @hide
+ */
+ @Readable
+ public static final String KEY_CHORD_POWER_VOLUME_UP =
+ "key_chord_power_volume_up";
/**
* Keyguard should be on the left hand side of the screen, for wide screen layouts.
diff --git a/core/java/android/service/dataloader/DataLoaderService.java b/core/java/android/service/dataloader/DataLoaderService.java
index 3ad80d3e97fa..63ec252c2fa8 100644
--- a/core/java/android/service/dataloader/DataLoaderService.java
+++ b/core/java/android/service/dataloader/DataLoaderService.java
@@ -39,24 +39,35 @@ import java.io.IOException;
import java.util.Collection;
/**
- * The base class for implementing data loader service to control data loaders. Expecting
- * Installation Session to bind to a children class of this.
+ * The base class for implementing a data loader service.
+ * <p>
+ * After calling commit() on the install session, the DataLoaderService is started and bound to
+ * provide the actual data bytes for the streaming session.
+ * The service will automatically be rebound until the streaming session has enough data to
+ * proceed with the installation.
+ *
+ * @see android.content.pm.DataLoaderParams
+ * @see android.content.pm.PackageInstaller.SessionParams#setDataLoaderParams
*/
public abstract class DataLoaderService extends Service {
private static final String TAG = "DataLoaderService";
private final DataLoaderBinderService mBinder = new DataLoaderBinderService();
/**
- * Managed DataLoader interface. Each instance corresponds to a single installation session.
+ * DataLoader interface. Each instance corresponds to a single installation session.
*/
public interface DataLoader {
/**
* A virtual constructor.
*
* @param dataLoaderParams parameters set in the installation session
- * @param connector FS API wrapper
- * @return True if initialization of a Data Loader was successful. False will be reported to
- * PackageManager and fail the installation
+ * {@link android.content.pm.PackageInstaller.SessionParams#setDataLoaderParams}
+ * @param connector Wrapper providing access to the installation image.
+ * @return true if initialization of a DataLoader was successful. False will notify the
+ * Installer {@link android.content.pm.PackageInstaller#STATUS_PENDING_STREAMING} and
+ * interrupt the session commit. The Installer is supposed to make sure DataLoader can
+ * proceed and then commit the session
+ * {@link android.content.pm.PackageInstaller.Session#commit}.
*/
boolean onCreate(@NonNull DataLoaderParams dataLoaderParams,
@NonNull FileSystemConnector connector);
@@ -64,10 +75,35 @@ public abstract class DataLoaderService extends Service {
/**
* Prepare installation image. After this method succeeds installer will validate the files
* and continue installation.
+ * The method should block until the files are prepared for installation.
+ * This can take up to session lifetime (~day). If the session lifetime is exceeded then
+ * any attempts to write new data will fail.
+ *
+ * Example implementation:
+ * <code>
+ * String localPath = "/data/local/tmp/base.apk";
+ * session.addFile(LOCATION_DATA_APP, "base", 123456, localPath.getBytes(UTF_8), null);
+ * ...
+ * // onPrepareImage
+ * for (InstallationFile file : addedFiles) {
+ * String localPath = new String(file.getMetadata(), UTF_8);
+ * File source = new File(localPath);
+ * ParcelFileDescriptor fd = ParcelFileDescriptor.open(source, MODE_READ_ONLY);
+ * try {
+ * mConnector.writeData(file.getName(), 0, fd.getStatSize(), fd);
+ * } finally {
+ * IoUtils.closeQuietly(fd);
+ * }
+ * }
+ * </code>
+ * It is recommended to stream data into installation session directly from source, e.g.
+ * cloud data storage, to save local disk space.
*
- * @param addedFiles list of files created in this installation session.
- * @param removedFiles list of files removed in this installation session.
- * @return false if unable to create and populate all addedFiles.
+ * @param addedFiles list of files created in this installation session
+ * {@link android.content.pm.PackageInstaller.Session#addFile}
+ * @param removedFiles list of files removed in this installation session
+ * {@link android.content.pm.PackageInstaller.Session#removeFile}
+ * @return false if unable to create and populate all addedFiles. Installation will fail.
*/
boolean onPrepareImage(@NonNull Collection<InstallationFile> addedFiles,
@NonNull Collection<String> removedFiles);
@@ -75,8 +111,7 @@ public abstract class DataLoaderService extends Service {
/**
* DataLoader factory method.
- *
- * @return An instance of a DataLoader.
+ * An installation session uses it to create an instance of DataLoader.
*/
public @Nullable DataLoader onCreateDataLoader(@NonNull DataLoaderParams dataLoaderParams) {
return null;
@@ -142,7 +177,7 @@ public abstract class DataLoaderService extends Service {
}
/**
- * Used by the DataLoaderService implementations.
+ * Provides access to the installation image.
*/
public static final class FileSystemConnector {
/**
@@ -157,7 +192,8 @@ public abstract class DataLoaderService extends Service {
/**
* Write data to an installation file from an arbitrary FD.
*
- * @param name name of file previously added to the installation session.
+ * @param name name of file previously added to the installation session
+ * {@link InstallationFile#getName()}.
* @param offsetBytes offset into the file to begin writing at, or 0 to start at the
* beginning of the file.
* @param lengthBytes total size of the file being written, used to preallocate the
diff --git a/core/java/android/service/displayhash/DisplayHashParams.java b/core/java/android/service/displayhash/DisplayHashParams.java
index 6a176a338d2e..fcce91ab6f1f 100644
--- a/core/java/android/service/displayhash/DisplayHashParams.java
+++ b/core/java/android/service/displayhash/DisplayHashParams.java
@@ -46,11 +46,6 @@ public final class DisplayHashParams implements Parcelable {
private final Size mBufferSize;
/**
- * Whether the content captured will use filtering when scaling.
- */
- private final boolean mBufferScaleWithFiltering;
-
- /**
* Whether the content will be captured in grayscale or color.
*/
private final boolean mGrayscaleBuffer;
@@ -61,7 +56,6 @@ public final class DisplayHashParams implements Parcelable {
public static final class Builder {
@Nullable
private Size mBufferSize;
- private boolean mBufferScaleWithFiltering;
private boolean mGrayscaleBuffer;
/**
@@ -80,15 +74,6 @@ public final class DisplayHashParams implements Parcelable {
}
/**
- * Whether the content captured will use filtering when scaling.
- */
- @NonNull
- public Builder setBufferScaleWithFiltering(boolean value) {
- mBufferScaleWithFiltering = value;
- return this;
- }
-
- /**
* Whether the content will be captured in grayscale or color.
*/
@NonNull
@@ -100,13 +85,13 @@ public final class DisplayHashParams implements Parcelable {
/** Builds the instance. This builder should not be touched after calling this! */
@NonNull
public DisplayHashParams build() {
- return new DisplayHashParams(mBufferSize, mBufferScaleWithFiltering, mGrayscaleBuffer);
+ return new DisplayHashParams(mBufferSize, mGrayscaleBuffer);
}
}
- // Code below generated by codegen v1.0.22.
+ // Code below generated by codegen v1.0.23.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -127,8 +112,6 @@ public final class DisplayHashParams implements Parcelable {
* buffer given to the {@link DisplayHasherService#onGenerateDisplayHash(byte[], HardwareBuffer,
* Rect, String, DisplayHashResultCallback)} will be stretched based on the value set here.
* If {@code null}, the buffer size will not be changed.
- * @param bufferScaleWithFiltering
- * Whether the content captured will use filtering when scaling.
* @param grayscaleBuffer
* Whether the content will be captured in grayscale or color.
* @hide
@@ -136,10 +119,8 @@ public final class DisplayHashParams implements Parcelable {
@DataClass.Generated.Member
public DisplayHashParams(
@Nullable Size bufferSize,
- boolean bufferScaleWithFiltering,
boolean grayscaleBuffer) {
this.mBufferSize = bufferSize;
- this.mBufferScaleWithFiltering = bufferScaleWithFiltering;
this.mGrayscaleBuffer = grayscaleBuffer;
// onConstructed(); // You can define this method to get a callback
@@ -157,14 +138,6 @@ public final class DisplayHashParams implements Parcelable {
}
/**
- * Whether the content captured will use filtering when scaling.
- */
- @DataClass.Generated.Member
- public boolean isBufferScaleWithFiltering() {
- return mBufferScaleWithFiltering;
- }
-
- /**
* Whether the content will be captured in grayscale or color.
*/
@DataClass.Generated.Member
@@ -180,7 +153,6 @@ public final class DisplayHashParams implements Parcelable {
return "DisplayHashParams { " +
"bufferSize = " + mBufferSize + ", " +
- "bufferScaleWithFiltering = " + mBufferScaleWithFiltering + ", " +
"grayscaleBuffer = " + mGrayscaleBuffer +
" }";
}
@@ -192,8 +164,7 @@ public final class DisplayHashParams implements Parcelable {
// void parcelFieldName(Parcel dest, int flags) { ... }
byte flg = 0;
- if (mBufferScaleWithFiltering) flg |= 0x2;
- if (mGrayscaleBuffer) flg |= 0x4;
+ if (mGrayscaleBuffer) flg |= 0x2;
if (mBufferSize != null) flg |= 0x1;
dest.writeByte(flg);
if (mBufferSize != null) dest.writeSize(mBufferSize);
@@ -211,12 +182,10 @@ public final class DisplayHashParams implements Parcelable {
// static FieldType unparcelFieldName(Parcel in) { ... }
byte flg = in.readByte();
- boolean bufferScaleWithFiltering = (flg & 0x2) != 0;
- boolean grayscaleBuffer = (flg & 0x4) != 0;
+ boolean grayscaleBuffer = (flg & 0x2) != 0;
Size bufferSize = (flg & 0x1) == 0 ? null : (Size) in.readSize();
this.mBufferSize = bufferSize;
- this.mBufferScaleWithFiltering = bufferScaleWithFiltering;
this.mGrayscaleBuffer = grayscaleBuffer;
// onConstructed(); // You can define this method to get a callback
@@ -237,10 +206,10 @@ public final class DisplayHashParams implements Parcelable {
};
@DataClass.Generated(
- time = 1615565493989L,
- codegenVersion = "1.0.22",
+ time = 1617735166254L,
+ codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/service/displayhash/DisplayHashParams.java",
- inputSignatures = "private final @android.annotation.Nullable android.util.Size mBufferSize\nprivate final boolean mBufferScaleWithFiltering\nprivate final boolean mGrayscaleBuffer\nclass DisplayHashParams extends java.lang.Object implements [android.os.Parcelable]\nprivate @android.annotation.Nullable android.util.Size mBufferSize\nprivate boolean mBufferScaleWithFiltering\nprivate boolean mGrayscaleBuffer\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams.Builder setBufferSize(int,int)\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams.Builder setBufferScaleWithFiltering(boolean)\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams.Builder setGrayscaleBuffer(boolean)\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams build()\nclass Builder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genAidl=true, genToString=true, genParcelable=true, genHiddenConstructor=true)")
+ inputSignatures = "private final @android.annotation.Nullable android.util.Size mBufferSize\nprivate final boolean mGrayscaleBuffer\nclass DisplayHashParams extends java.lang.Object implements [android.os.Parcelable]\nprivate @android.annotation.Nullable android.util.Size mBufferSize\nprivate boolean mGrayscaleBuffer\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams.Builder setBufferSize(int,int)\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams.Builder setGrayscaleBuffer(boolean)\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams build()\nclass Builder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genAidl=true, genToString=true, genParcelable=true, genHiddenConstructor=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/service/resumeonreboot/OWNERS b/core/java/android/service/resumeonreboot/OWNERS
new file mode 100644
index 000000000000..3a127d5a2c12
--- /dev/null
+++ b/core/java/android/service/resumeonreboot/OWNERS
@@ -0,0 +1,2 @@
+xunchang@google.com
+zhaojiac@google.com
diff --git a/core/java/android/service/resumeonreboot/ResumeOnRebootService.java b/core/java/android/service/resumeonreboot/ResumeOnRebootService.java
index ad49ffd57dc2..247d9c4797e2 100644
--- a/core/java/android/service/resumeonreboot/ResumeOnRebootService.java
+++ b/core/java/android/service/resumeonreboot/ResumeOnRebootService.java
@@ -59,11 +59,9 @@ import java.io.IOException;
* &lt;/service&gt;
* </pre>
*
- * //TODO: Replace this with public link when available.
- *
* @hide
* @see
- * <a href="https://goto.google.com/server-based-ror">https://goto.google.com/server-based-ror</a>
+ * <a href="https://source.android.com/devices/tech/ota/resume-on-reboot">https://source.android.com/devices/tech/ota/resume-on-reboot</a>
*/
@SystemApi
public abstract class ResumeOnRebootService extends Service {
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 5c65c659e576..7b3a8a64fc37 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -737,7 +737,7 @@ public final class Choreographer {
}
mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos, vsyncEventData.id,
- vsyncEventData.frameDeadline);
+ vsyncEventData.frameDeadline, startNanos);
mFrameScheduled = false;
mLastFrameTimeNanos = frameTimeNanos;
mLastVsyncEventData = vsyncEventData;
diff --git a/core/java/android/view/FrameMetrics.java b/core/java/android/view/FrameMetrics.java
index eb49e52d5050..9cdf91a55c39 100644
--- a/core/java/android/view/FrameMetrics.java
+++ b/core/java/android/view/FrameMetrics.java
@@ -242,18 +242,19 @@ public final class FrameMetrics {
int PERFORM_TRAVERSALS_START = 7;
int DRAW_START = 8;
int FRAME_DEADLINE = 9;
- int SYNC_QUEUED = 10;
- int SYNC_START = 11;
- int ISSUE_DRAW_COMMANDS_START = 12;
- int SWAP_BUFFERS = 13;
- int FRAME_COMPLETED = 14;
- int DEQUEUE_BUFFER_DURATION = 15;
- int QUEUE_BUFFER_DURATION = 16;
- int GPU_COMPLETED = 17;
- int SWAP_BUFFERS_COMPLETED = 18;
- int DISPLAY_PRESENT_TIME = 19;
+ int FRAME_START_TIME = 10;
+ int SYNC_QUEUED = 11;
+ int SYNC_START = 12;
+ int ISSUE_DRAW_COMMANDS_START = 13;
+ int SWAP_BUFFERS = 14;
+ int FRAME_COMPLETED = 15;
+ int DEQUEUE_BUFFER_DURATION = 16;
+ int QUEUE_BUFFER_DURATION = 17;
+ int GPU_COMPLETED = 18;
+ int SWAP_BUFFERS_COMPLETED = 19;
+ int DISPLAY_PRESENT_TIME = 20;
- int FRAME_STATS_COUNT = 20; // must always be last and in sync with
+ int FRAME_STATS_COUNT = 21; // must always be last and in sync with
// FrameInfoIndex::NumIndexes in libs/hwui/FrameInfo.h
}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index d0a3e4b86e2d..0f032e906991 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -786,29 +786,60 @@ interface IWindowManager
void setDisplayHashThrottlingEnabled(boolean enable);
/**
- * Registers a listener for a {@link android.window.WindowContext} to handle configuration
- * changes from the server side.
+ * Attaches a {@link android.window.WindowContext} to the DisplayArea specified by {@code type},
+ * {@code displayId} and {@code options}.
* <p>
* Note that this API should be invoked after calling
* {@link android.window.WindowTokenClient#attachContext(Context)}
- * </p>
+ * </p><p>
+ * Generally, this API is used for initializing a {@link android.window.WindowContext}
+ * before obtaining a valid {@link com.android.server.wm.WindowToken}. A WindowToken is usually
+ * generated when calling {@link android.view.WindowManager#addView(View, LayoutParams)}, or
+ * obtained from {@link android.view.WindowManager.LayoutParams#token}.
+ * </p><p>
+ * In some cases, the WindowToken is passed from the server side because it is managed by the
+ * system server. {@link #attachWindowContextToWindowToken(IBinder, IBinder)} could be used in
+ * this case to attach the WindowContext to the WindowToken.</p>
*
- * @param clientToken the window context's token
+ * @param clientToken {@link android.window.WindowContext#getWindowContextToken()
+ * the WindowContext's token}
* @param type Window type of the window context
* @param displayId The display associated with the window context
* @param options A bundle used to pass window-related options and choose the right DisplayArea
*
- * @return {@code true} if the listener was registered successfully.
+ * @return {@code true} if the WindowContext is attached to the DisplayArea successfully.
*/
- boolean registerWindowContextListener(IBinder clientToken, int type, int displayId,
+ boolean attachWindowContextToDisplayArea(IBinder clientToken, int type, int displayId,
in Bundle options);
/**
- * Unregisters a listener which registered with {@link #registerWindowContextListener()}.
+ * Attaches a {@link android.window.WindowContext} to a {@code WindowToken}.
+ * <p>
+ * This API is used when we hold a valid WindowToken and want to associate with the token and
+ * receive its configuration updates.
+ * </p><p>
+ * Note that this API should be invoked after calling
+ * {@link android.window.WindowTokenClient#attachContext(Context)}
+ * </p>
+ *
+ * @param clientToken {@link android.window.WindowContext#getWindowContextToken()
+ * the WindowContext's token}
+ * @param token the WindowToken to attach
+ *
+ * @throws IllegalArgumentException if the {@code clientToken} have not been attached to
+ * the server or the WindowContext's type doesn't match WindowToken {@code token}'s type.
+ *
+ * @see #attachWindowContextToDisplayArea(IBinder, int, int, Bundle)
+ */
+ void attachWindowContextToWindowToken(IBinder clientToken, IBinder token);
+
+ /**
+ * Detaches {@link android.window.WindowContext} from the window manager node it's currently
+ * attached to. It is no-op if the WindowContext is not attached to a window manager node.
*
* @param clientToken the window context's token
*/
- void unregisterWindowContextListener(IBinder clientToken);
+ void detachWindowContextFromWindowContainer(IBinder clientToken);
/**
* Registers a listener, which is to be called whenever cross-window blur is enabled/disabled.
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index d1f8ee9b0cc7..3b1c8ec23016 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -812,7 +812,9 @@ public final class InputDevice implements Parcelable {
* {@link Context#getSystemService} with {@link Context#VIBRATOR_SERVICE} as argument.
*
* @return The vibrator service associated with the device, never null.
+ * @deprecated Use {@link #getVibratorManager()} to retrieve the default device vibrator.
*/
+ @Deprecated
public Vibrator getVibrator() {
synchronized (mMotionRanges) {
if (mVibrator == null) {
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index b6b8a2daf160..c201e3beb9b2 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -601,6 +601,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
return;
}
+ mTmpFinishedControls.clear();
+ mTmpRunningAnims.clear();
InsetsState state = new InsetsState(mState, true /* copySources */);
for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
RunningAnimation runningAnimation = mRunningAnimations.get(i);
@@ -633,12 +635,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
anim.getTypeMask(), anim.getInterpolatedFraction()));
}
}
- mTmpRunningAnims.clear();
for (int i = mTmpFinishedControls.size() - 1; i >= 0; i--) {
dispatchAnimationEnd(mTmpFinishedControls.get(i).getAnimation());
}
- mTmpFinishedControls.clear();
};
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index dd5c95404510..d6b5a2c299e9 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9285,6 +9285,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* parentView.addView(reusableView);
* </pre>
*
+ * <p>NOTE: If this view is a descendant of an {@link android.widget.AdapterView}, the system
+ * may reset its autofill id when this view is recycled. If the autofill ids need to be stable,
+ * they should be set again in
+ * {@link android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup)}.
+ *
* @param id an autofill ID that is unique in the {@link android.app.Activity} hosting the view,
* or {@code null} to reset it. Usually it's an id previously allocated to another view (and
* obtained through {@link #getAutofillId()}), or a new value obtained through
@@ -9321,6 +9326,30 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Forces a reset of the autofill ids of the subtree rooted at this view. Like calling
+ * {@link #setAutofillId(AutofillId) setAutofillId(null)} for each view, but works even if the
+ * views are attached to a window.
+ *
+ * <p>This is useful if the views are being recycled, since an autofill id should uniquely
+ * identify a particular piece of content.
+ *
+ * @hide
+ */
+ public void resetSubtreeAutofillIds() {
+ if (mAutofillViewId == NO_ID) {
+ return;
+ }
+ if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) {
+ Log.v(CONTENT_CAPTURE_LOG_TAG, "resetAutofillId() for " + mAutofillViewId);
+ } else if (Log.isLoggable(AUTOFILL_LOG_TAG, Log.VERBOSE)) {
+ Log.v(AUTOFILL_LOG_TAG, "resetAutofillId() for " + mAutofillViewId);
+ }
+ mAutofillId = null;
+ mAutofillViewId = NO_ID;
+ mPrivateFlags3 &= ~PFLAG3_AUTOFILLID_EXPLICITLY_SET;
+ }
+
+ /**
* Describes the autofill type of this view, so an
* {@link android.service.autofill.AutofillService} can create the proper {@link AutofillValue}
* when autofilling the view.
@@ -30843,8 +30872,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* {@link android.view.translation.Translator} to translate the requests. All the
* {@link ViewTranslationRequest}s must be added when the traversal is done.
*
- * <p> The default implementation will call {@link View#onCreateTranslationRequest} to build
- * {@link ViewTranslationRequest} if the view should be translated. </p>
+ * <p> The default implementation calls {@link View#onCreateTranslationRequest} to build
+ * {@link ViewTranslationRequest} if the view should be translated. The view is marked as having
+ * {@link #setHasTransientState(boolean) transient state} so that recycling of views doesn't
+ * prevent the system from attaching the response to it.</p>
*
* @param viewIds a map for the view's {@link AutofillId} and its virtual child ids or
* {@code null} if the view doesn't have virtual child that should be translated. The virtual
@@ -30865,6 +30896,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
ViewTranslationRequest request = onCreateTranslationRequest(supportedFormats);
if (request != null && request.getKeys().size() > 0) {
requests.add(request);
+ if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) {
+ Log.v(CONTENT_CAPTURE_LOG_TAG, "Calling setHasTransientState(true) for "
+ + autofillId);
+ }
+ // TODO: Add a default ViewTranslationCallback for View that resets this in
+ // onClearTranslation(). Also update the javadoc for this method to mention
+ // that.
+ setHasTransientState(true);
}
} else {
onCreateTranslationRequests(viewIds.get(autofillId), supportedFormats, request -> {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 5b695f4c425a..04e2cdee56a0 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3773,6 +3773,17 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
/** @hide */
@Override
+ public void resetSubtreeAutofillIds() {
+ super.resetSubtreeAutofillIds();
+ View[] children = mChildren;
+ final int childCount = mChildrenCount;
+ for (int i = 0; i < childCount; i++) {
+ children[i].resetSubtreeAutofillIds();
+ }
+ }
+
+ /** @hide */
+ @Override
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfoInternal(info);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 4b56fd740e8d..cca8257645fe 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -921,6 +921,30 @@ public interface WindowManager extends ViewManager {
default void setForceCrossWindowBlurDisabled(boolean disable) {
}
+ /**
+ * @hide
+ */
+ static String transitTypeToString(@TransitionType int type) {
+ switch (type) {
+ case TRANSIT_NONE: return "NONE";
+ case TRANSIT_OPEN: return "OPEN";
+ case TRANSIT_CLOSE: return "CLOSE";
+ case TRANSIT_TO_FRONT: return "TO_FRONT";
+ case TRANSIT_TO_BACK: return "TO_BACK";
+ case TRANSIT_RELAUNCH: return "RELAUNCH";
+ case TRANSIT_CHANGE: return "CHANGE";
+ case TRANSIT_KEYGUARD_GOING_AWAY: return "KEYGUARD_GOING_AWAY";
+ case TRANSIT_KEYGUARD_OCCLUDE: return "KEYGUARD_OCCLUDE";
+ case TRANSIT_KEYGUARD_UNOCCLUDE: return "KEYGUARD_UNOCCLUDE";
+ case TRANSIT_FIRST_CUSTOM: return "FIRST_CUSTOM";
+ default:
+ if (type > TRANSIT_FIRST_CUSTOM) {
+ return "FIRST_CUSTOM+" + (type - TRANSIT_FIRST_CUSTOM);
+ }
+ return "UNKNOWN(" + type + ")";
+ }
+ }
+
public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
/**
* X position for this window. With the default gravity it is ignored.
diff --git a/core/java/android/view/translation/TranslationManager.java b/core/java/android/view/translation/TranslationManager.java
index b89488b715c9..b61eab97779e 100644
--- a/core/java/android/view/translation/TranslationManager.java
+++ b/core/java/android/view/translation/TranslationManager.java
@@ -18,12 +18,10 @@ package android.view.translation;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.RequiresFeature;
import android.annotation.SystemService;
import android.annotation.WorkerThread;
import android.app.PendingIntent;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
@@ -53,7 +51,6 @@ import java.util.concurrent.atomic.AtomicInteger;
* the server {@link android.service.translation.TranslationService} </p>
*/
@SystemService(Context.TRANSLATION_MANAGER_SERVICE)
-@RequiresFeature(PackageManager.FEATURE_TRANSLATION)
public final class TranslationManager {
private static final String TAG = "TranslationManager";
diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java
index 53e354f8200e..f4fdf35fb50f 100644
--- a/core/java/android/view/translation/UiTranslationController.java
+++ b/core/java/android/view/translation/UiTranslationController.java
@@ -388,7 +388,7 @@ public class UiTranslationController {
private void sendTranslationRequest(Translator translator,
List<ViewTranslationRequest> requests) {
if (requests.size() == 0) {
- Log.wtf(TAG, "No ViewTranslationRequest was collected.");
+ Log.w(TAG, "No ViewTranslationRequest was collected.");
return;
}
final TranslationRequest request = new TranslationRequest.Builder()
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 94a0790c86a2..eb16cef15248 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -6425,6 +6425,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (lp != null && mRecycler.shouldRecycleViewType(lp.viewType)) {
views.add(child);
child.setAccessibilityDelegate(null);
+ child.resetSubtreeAutofillIds();
if (listener != null) {
// Pretend they went through the scrap heap
listener.onMovedToScrapHeap(child);
@@ -7365,10 +7366,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
private void clearScrapForRebind(View view) {
view.clearAccessibilityFocus();
view.setAccessibilityDelegate(null);
+ view.resetSubtreeAutofillIds();
}
private void removeDetachedView(View child, boolean animate) {
child.setAccessibilityDelegate(null);
+ child.resetSubtreeAutofillIds();
AbsListView.this.removeDetachedView(child, animate);
}
}
diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java
index ae426d2c897f..50fca043d4e0 100644
--- a/core/java/android/widget/EdgeEffect.java
+++ b/core/java/android/widget/EdgeEffect.java
@@ -626,20 +626,14 @@ public class EdgeEffect {
// assume rotations of increments of 90 degrees
float x = mTmpPoints[10] - mTmpPoints[8];
float width = right - left;
- float vecX = 0f;
- if (width > 0) {
- vecX = dampStretchVector(Math.max(-1f, Math.min(1f, x / width)));
- }
+ float vecX = dampStretchVector(Math.max(-1f, Math.min(1f, x / width)));
float y = mTmpPoints[11] - mTmpPoints[9];
float height = bottom - top;
- float vecY = 0f;
- if (height > 0) {
- vecY = dampStretchVector(Math.max(-1f, Math.min(1f, y / height)));
- }
+ float vecY = dampStretchVector(Math.max(-1f, Math.min(1f, y / height)));
- boolean hasStretchVectors = Float.compare(vecX, 0) != 0 || Float.compare(vecY, 0) != 0;
- if (right > left && bottom > top && mWidth > 0 && mHeight > 0 && hasStretchVectors) {
+ boolean hasValidVectors = Float.isFinite(vecX) && Float.isFinite(vecY);
+ if (right > left && bottom > top && mWidth > 0 && mHeight > 0 && hasValidVectors) {
renderNode.stretch(
left,
top,
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 23915e06335a..105c714930a2 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -762,11 +762,11 @@ public class HorizontalScrollView extends FrameLayout {
if (canOverscroll) {
int consumed = 0;
if (deltaX < 0 && mEdgeGlowRight.getDistance() != 0f) {
- consumed = Math.round(getHeight()
+ consumed = Math.round(getWidth()
* mEdgeGlowRight.onPullDistance((float) deltaX / getWidth(),
displacement));
} else if (deltaX > 0 && mEdgeGlowLeft.getDistance() != 0f) {
- consumed = Math.round(-getHeight()
+ consumed = Math.round(-getWidth()
* mEdgeGlowLeft.onPullDistance((float) -deltaX / getWidth(),
1 - displacement));
}
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java
index 3b35b6dfc889..f1515276e2c6 100644
--- a/core/java/android/window/TransitionInfo.java
+++ b/core/java/android/window/TransitionInfo.java
@@ -23,6 +23,7 @@ import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
+import static android.view.WindowManager.transitTypeToString;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -205,7 +206,7 @@ public final class TransitionInfo implements Parcelable {
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
- sb.append("{t=" + mType + " f=" + Integer.toHexString(mFlags)
+ sb.append("{t=" + transitTypeToString(mType) + " f=" + Integer.toHexString(mFlags)
+ " ro=" + mRootOffset + " c=[");
for (int i = 0; i < mChanges.size(); ++i) {
if (i > 0) {
diff --git a/core/java/android/window/WindowContext.java b/core/java/android/window/WindowContext.java
index 375f4cf63c3b..901625b0732c 100644
--- a/core/java/android/window/WindowContext.java
+++ b/core/java/android/window/WindowContext.java
@@ -57,6 +57,8 @@ public class WindowContext extends ContextWrapper {
*
* @param base Base {@link Context} for this new instance.
* @param type Window type to be used with this context.
+ * @param options A bundle used to pass window-related options.
+ *
* @hide
*/
public WindowContext(@NonNull Context base, int type, @Nullable Bundle options) {
@@ -72,11 +74,12 @@ public class WindowContext extends ContextWrapper {
}
/**
- * Registers this {@link WindowContext} with {@link com.android.server.wm.WindowManagerService}
- * to receive configuration changes of the associated {@link WindowManager} node.
+ * Attaches this {@link WindowContext} to the {@link com.android.server.wm.DisplayArea}
+ * specified by {@code mType}, {@link #getDisplayId() display ID} and {@code mOptions}
+ * to receive configuration changes.
*/
- public void registerWithServer() {
- mController.registerListener(mType, getDisplayId(), mOptions);
+ public void attachToDisplayArea() {
+ mController.attachToDisplayArea(mType, getDisplayId(), mOptions);
}
@Override
@@ -96,7 +99,7 @@ public class WindowContext extends ContextWrapper {
/** Used for test to invoke because we can't invoke finalize directly. */
@VisibleForTesting
public void release() {
- mController.unregisterListenerIfNeeded();
+ mController.detachIfNeeded();
destroy();
}
diff --git a/core/java/android/window/WindowContextController.java b/core/java/android/window/WindowContextController.java
index 61434145290f..88584f4b2571 100644
--- a/core/java/android/window/WindowContextController.java
+++ b/core/java/android/window/WindowContextController.java
@@ -29,22 +29,29 @@ import android.view.WindowManagerGlobal;
import com.android.internal.annotations.VisibleForTesting;
/**
- * The controller to manage {@link WindowContext} listener, such as registering and unregistering
- * the listener.
+ * The controller to manage {@link WindowContext}, such as attaching to a window manager node or
+ * detaching from the current attached node. The user must call
+ * {@link #attachToDisplayArea(int, int, Bundle)}, call {@link #attachToWindowToken(IBinder)}
+ * after that if necessary, and then call {@link #detachIfNeeded()} for release.
*
* @hide
*/
public class WindowContextController {
private final IWindowManager mWms;
+ /**
+ * {@code true} to indicate that the {@code mToken} is associated with a
+ * {@link com.android.server.wm.DisplayArea}. Note that {@code mToken} is able to attach a
+ * WindowToken after this flag sets to {@code true}.
+ */
@VisibleForTesting
- public boolean mListenerRegistered;
+ public boolean mAttachedToDisplayArea;
@NonNull
private final IBinder mToken;
/**
* Window Context Controller constructor
*
- * @param token The token to register to the window context listener. It is usually from
+ * @param token The token used to attach to a window manager node. It is usually from
* {@link Context#getWindowContextToken()}.
*/
public WindowContextController(@NonNull IBinder token) {
@@ -60,19 +67,21 @@ public class WindowContextController {
}
/**
- * Registers the {@code mToken} to the window context listener.
+ * Attaches the {@code mToken} to a {@link com.android.server.wm.DisplayArea}.
*
* @param type The window type of the {@link WindowContext}
* @param displayId The {@link Context#getDisplayId() ID of display} to associate with
* @param options The window context launched option
+ * @throws IllegalStateException if the {@code mToken} has already been attached to a
+ * DisplayArea.
*/
- public void registerListener(@WindowType int type, int displayId, @Nullable Bundle options) {
- if (mListenerRegistered) {
- throw new UnsupportedOperationException("A Window Context can only register a listener"
- + " once.");
+ public void attachToDisplayArea(@WindowType int type, int displayId, @Nullable Bundle options) {
+ if (mAttachedToDisplayArea) {
+ throw new IllegalStateException("A Window Context can be only attached to "
+ + "a DisplayArea once.");
}
try {
- mListenerRegistered = mWms.registerWindowContextListener(mToken, type, displayId,
+ mAttachedToDisplayArea = mWms.attachWindowContextToDisplayArea(mToken, type, displayId,
options);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -80,14 +89,42 @@ public class WindowContextController {
}
/**
- * Unregisters the window context listener associated with the {@code mToken} if it has been
- * registered.
+ * Switches to attach the window context to a window token.
+ * <p>
+ * Note that the context should have been attached to a
+ * {@link com.android.server.wm.DisplayArea} by {@link #attachToDisplayArea(int, int, Bundle)}
+ * before attaching to a window token, and the window token's type must match the window
+ * context's type.
+ * </p><p>
+ * A {@link WindowContext} can only attach to a specific window manager node, which is either a
+ * {@link com.android.server.wm.DisplayArea} by calling
+ * {@link #attachToDisplayArea(int, int, Bundle)} or the latest attached {@code windowToken}
+ * although this API is allowed to be called multiple times.
+ * </p>
+ * @throws IllegalStateException if the {@code mClientToken} has not yet attached to
+ * a {@link com.android.server.wm.DisplayArea} by
+ * {@link #attachToDisplayArea(int, int, Bundle)}.
+ *
+ * @see IWindowManager#attachWindowContextToWindowToken(IBinder, IBinder)
*/
- public void unregisterListenerIfNeeded() {
- if (mListenerRegistered) {
+ public void attachToWindowToken(IBinder windowToken) {
+ if (!mAttachedToDisplayArea) {
+ throw new IllegalStateException("The Window Context should have been attached"
+ + " to a DisplayArea.");
+ }
+ try {
+ mWms.attachWindowContextToWindowToken(mToken, windowToken);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /** Detaches the window context from the node it's currently associated with. */
+ public void detachIfNeeded() {
+ if (mAttachedToDisplayArea) {
try {
- mWms.unregisterWindowContextListener(mToken);
- mListenerRegistered = false;
+ mWms.detachWindowContextFromWindowContainer(mToken);
+ mAttachedToDisplayArea = false;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/com/android/internal/os/BinderLatencyBuckets.java b/core/java/com/android/internal/os/BinderLatencyBuckets.java
new file mode 100644
index 000000000000..bdee4ca8a6b8
--- /dev/null
+++ b/core/java/com/android/internal/os/BinderLatencyBuckets.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2017 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.os;
+
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * Generates the bucket thresholds (with a custom logarithmic scale) for a histogram to store
+ * latency samples in.
+ */
+public class BinderLatencyBuckets {
+ private static final String TAG = "BinderLatencyBuckets";
+ private ArrayList<Integer> mBuckets;
+
+ /**
+ * @param bucketCount the number of buckets the histogram should have
+ * @param firstBucketSize the size of the first bucket (used to avoid excessive small buckets)
+ * @param scaleFactor the rate in which each consecutive bucket increases (before rounding)
+ */
+ public BinderLatencyBuckets(int bucketCount, int firstBucketSize, float scaleFactor) {
+ mBuckets = new ArrayList<>(bucketCount - 1);
+ mBuckets.add(firstBucketSize);
+
+ // Last value and the target are disjoint as we never want to create buckets smaller than 1.
+ double lastTarget = firstBucketSize;
+ int lastValue = firstBucketSize;
+
+ // First bucket is already created and the last bucket is anything greater than the final
+ // bucket in the list, so create 'bucketCount' - 2 buckets.
+ for (int i = 1; i < bucketCount - 1; i++) {
+ // Increase the target bucket limit value by the scale factor.
+ double nextTarget = lastTarget * scaleFactor;
+
+ if (nextTarget > Integer.MAX_VALUE || lastValue == Integer.MAX_VALUE) {
+ // Do not throw an exception here as this should not affect binder calls.
+ Slog.w(TAG, "Attempted to create a bucket larger than maxint");
+ return;
+ }
+
+ if ((int) nextTarget > lastValue) {
+ // Convert the target bucket limit value to an integer.
+ mBuckets.add((int) nextTarget);
+ lastValue = (int) nextTarget;
+ } else {
+ // Avoid creating redundant buckets, so bucket size should be 1 at a minimum.
+ mBuckets.add(lastValue + 1);
+ lastValue = lastValue + 1;
+ }
+ lastTarget = nextTarget;
+ }
+ }
+
+ /** Gets the bucket index to insert the provided sample in. */
+ public int sampleToBucket(int sample) {
+ if (sample > mBuckets.get(mBuckets.size() - 1)) {
+ return mBuckets.size();
+ }
+
+ // Binary search returns the element index if it is contained in the list - in this case the
+ // correct bucket is the index after as we use [minValue, maxValue) for bucket boundaries.
+ // Otherwise, it returns (-(insertion point) - 1), where insertion point is the point where
+ // to insert the element so that the array remains sorted - in this case the bucket index
+ // is the insertion point.
+ int searchResult = Collections.binarySearch(mBuckets, sample);
+ return searchResult < 0 ? -(1 + searchResult) : searchResult + 1;
+ }
+
+ @VisibleForTesting
+ public ArrayList<Integer> getBuckets() {
+ return mBuckets;
+ }
+}
diff --git a/core/java/com/android/internal/os/BinderLatencyObserver.java b/core/java/com/android/internal/os/BinderLatencyObserver.java
index 92b495284de2..59cc66d79bce 100644
--- a/core/java/com/android/internal/os/BinderLatencyObserver.java
+++ b/core/java/com/android/internal/os/BinderLatencyObserver.java
@@ -26,7 +26,6 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BinderInternal.CallSession;
-import java.util.ArrayList;
import java.util.Random;
/** Collects statistics about Binder call latency per calling API and method. */
@@ -34,18 +33,25 @@ public class BinderLatencyObserver {
private static final String TAG = "BinderLatencyObserver";
public static final int PERIODIC_SAMPLING_INTERVAL_DEFAULT = 10;
- // This is not the final data structure - we will eventually store latency histograms instead of
- // raw samples as it is much more memory / disk space efficient.
- // TODO(b/179999191): change this to store the histogram.
- // TODO(b/179999191): pre allocate the array size so we would not have to resize this.
+ // Histogram buckets parameters.
+ public static final int BUCKET_COUNT_DEFAULT = 100;
+ public static final int FIRST_BUCKET_SIZE_DEFAULT = 5;
+ public static final float BUCKET_SCALE_FACTOR_DEFAULT = 1.125f;
+
@GuardedBy("mLock")
- private final ArrayMap<LatencyDims, ArrayList<Long>> mLatencySamples = new ArrayMap<>();
+ private final ArrayMap<LatencyDims, int[]> mLatencyHistograms = new ArrayMap<>();
private final Object mLock = new Object();
// Sampling period to control how often to track CPU usage. 1 means all calls, 100 means ~1 out
// of 100 requests.
private int mPeriodicSamplingInterval = PERIODIC_SAMPLING_INTERVAL_DEFAULT;
+
+ private int mBucketCount = BUCKET_COUNT_DEFAULT;
+ private int mFirstBucketSize = FIRST_BUCKET_SIZE_DEFAULT;
+ private float mBucketScaleFactor = BUCKET_SCALE_FACTOR_DEFAULT;
+
private final Random mRandom;
+ private BinderLatencyBuckets mLatencyBuckets;
/** Injector for {@link BinderLatencyObserver}. */
public static class Injector {
@@ -56,6 +62,8 @@ public class BinderLatencyObserver {
public BinderLatencyObserver(Injector injector) {
mRandom = injector.getRandomGenerator();
+ mLatencyBuckets = new BinderLatencyBuckets(
+ mBucketCount, mFirstBucketSize, mBucketScaleFactor);
}
/** Should be called when a Binder call completes, will store latency data. */
@@ -67,12 +75,21 @@ public class BinderLatencyObserver {
LatencyDims dims = new LatencyDims(s.binderClass, s.transactionCode);
long callDuration = getElapsedRealtimeMicro() - s.timeStarted;
+ // Find the bucket this sample should go to.
+ int bucketIdx = mLatencyBuckets.sampleToBucket(
+ callDuration > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) callDuration);
+
synchronized (mLock) {
- if (!mLatencySamples.containsKey(dims)) {
- mLatencySamples.put(dims, new ArrayList<Long>());
+ int[] buckets = mLatencyHistograms.get(dims);
+ if (buckets == null) {
+ buckets = new int[mBucketCount];
+ mLatencyHistograms.put(dims, buckets);
}
- mLatencySamples.get(dims).add(callDuration);
+ // Increment the correct bucket.
+ if (buckets[bucketIdx] < Integer.MAX_VALUE) {
+ buckets[bucketIdx] += 1;
+ }
}
}
@@ -100,10 +117,26 @@ public class BinderLatencyObserver {
}
}
+ /** Updates the histogram buckets parameters. */
+ public void setHistogramBucketsParams(
+ int bucketCount, int firstBucketSize, float bucketScaleFactor) {
+ synchronized (mLock) {
+ if (bucketCount != mBucketCount || firstBucketSize != mFirstBucketSize
+ || bucketScaleFactor != mBucketScaleFactor) {
+ mBucketCount = bucketCount;
+ mFirstBucketSize = firstBucketSize;
+ mBucketScaleFactor = bucketScaleFactor;
+ mLatencyBuckets = new BinderLatencyBuckets(
+ mBucketCount, mFirstBucketSize, mBucketScaleFactor);
+ reset();
+ }
+ }
+ }
+
/** Resets the sample collection. */
public void reset() {
synchronized (mLock) {
- mLatencySamples.clear();
+ mLatencyHistograms.clear();
}
}
@@ -151,7 +184,7 @@ public class BinderLatencyObserver {
}
@VisibleForTesting
- public ArrayMap<LatencyDims, ArrayList<Long>> getLatencySamples() {
- return mLatencySamples;
+ public ArrayMap<LatencyDims, int[]> getLatencyHistograms() {
+ return mLatencyHistograms;
}
}
diff --git a/core/java/com/android/internal/os/ZygoteCommandBuffer.java b/core/java/com/android/internal/os/ZygoteCommandBuffer.java
index b61ae7acfacd..83a68ca3ab7e 100644
--- a/core/java/com/android/internal/os/ZygoteCommandBuffer.java
+++ b/core/java/com/android/internal/os/ZygoteCommandBuffer.java
@@ -176,7 +176,7 @@ class ZygoteCommandBuffer implements AutoCloseable {
/*
* Repeatedly fork children as above. It commonly does not return in the parent, but it may.
- * @return true in the chaild, false in the parent if we encounter a command we couldn't handle.
+ * @return true in the child, false in the parent if we encounter a command we couldn't handle.
*/
private static native boolean nativeForkRepeatedly(long /* NativeCommandBuffer* */ nbuffer,
int zygoteSocketRawFd,
diff --git a/core/java/com/android/internal/security/VerityUtils.java b/core/java/com/android/internal/security/VerityUtils.java
index ef703a996001..877026777ce3 100644
--- a/core/java/com/android/internal/security/VerityUtils.java
+++ b/core/java/com/android/internal/security/VerityUtils.java
@@ -60,7 +60,7 @@ public abstract class VerityUtils {
private static final boolean DEBUG = false;
public static boolean isFsVeritySupported() {
- return Build.VERSION.FIRST_SDK_INT >= Build.VERSION_CODES.R
+ return Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.R
|| SystemProperties.getInt("ro.apk_verity.mode", 0) == 2;
}
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index bac6bbe43c91..db536d3aaa4f 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -486,7 +486,7 @@ public class SystemConfig {
// Vendors are only allowed to customize these
int vendorPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PRIVAPP_PERMISSIONS
| ALLOW_ASSOCIATIONS;
- if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.O_MR1) {
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT <= Build.VERSION_CODES.O_MR1) {
// For backward compatibility
vendorPermissionFlag |= (ALLOW_PERMISSIONS | ALLOW_APP_CONFIGS);
}
@@ -538,9 +538,9 @@ public class SystemConfig {
int productPermissionFlag = ALLOW_FEATURES | ALLOW_LIBS | ALLOW_PERMISSIONS
| ALLOW_APP_CONFIGS | ALLOW_PRIVAPP_PERMISSIONS | ALLOW_HIDDENAPI_WHITELISTING
| ALLOW_ASSOCIATIONS | ALLOW_OVERRIDE_APP_RESTRICTIONS | ALLOW_IMPLICIT_BROADCASTS;
- if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.R) {
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT <= Build.VERSION_CODES.R) {
// TODO(b/157393157): This must check product interface enforcement instead of
- // FIRST_SDK_VERSION for the devices without product interface enforcement.
+ // DEVICE_INITIAL_SDK_INT for the devices without product interface enforcement.
productPermissionFlag = ALLOW_ALL;
}
readPermissions(Environment.buildPath(
@@ -1241,7 +1241,7 @@ public class SystemConfig {
addFeature(PackageManager.FEATURE_APP_ENUMERATION, 0);
}
- if (Build.VERSION.FIRST_SDK_INT >= Build.VERSION_CODES.Q) {
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.Q) {
addFeature(PackageManager.FEATURE_IPSEC_TUNNELS, 0);
}
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 354e3a4d67ed..906367b1fa94 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -1072,7 +1072,7 @@ static jobject convertDisplayModeToJavaObject(JNIEnv* env, const ui::DisplayMode
return object;
}
-jobject convertDeviceProductInfoToJavaObject(JNIEnv* env, const HdrCapabilities& capabilities) {
+jobject convertHdrCapabilitiesToJavaObject(JNIEnv* env, const HdrCapabilities& capabilities) {
const auto& types = capabilities.getSupportedHdrTypes();
std::vector<int32_t> intTypes;
for (auto type : types) {
@@ -1129,7 +1129,7 @@ static jobject nativeGetDynamicDisplayInfo(JNIEnv* env, jclass clazz, jobject to
static_cast<jint>(info.activeColorMode));
env->SetObjectField(object, gDynamicDisplayInfoClassInfo.hdrCapabilities,
- convertDeviceProductInfoToJavaObject(env, info.hdrCapabilities));
+ convertHdrCapabilitiesToJavaObject(env, info.hdrCapabilities));
env->SetBooleanField(object, gDynamicDisplayInfoClassInfo.autoLowLatencyModeSupported,
info.autoLowLatencyModeSupported);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 4749ab63fca6..925a212d10cb 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5982,6 +5982,12 @@
android:exported="false">
</activity>
+ <activity android:name="com.android.server.notification.NASLearnMoreActivity"
+ android:theme="@style/Theme.Dialog.Confirmation"
+ android:excludeFromRecents="true"
+ android:exported="false">
+ </activity>
+
<receiver android:name="com.android.server.BootReceiver"
android:exported="true"
android:systemUserOnly="true">
diff --git a/core/res/res/color/surface_light.xml b/core/res/res/color/surface_light.xml
index 4a230b12726c..169bfcdf1d41 100644
--- a/core/res/res/color/surface_light.xml
+++ b/core/res/res/color/surface_light.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="@color/system_neutral1_500" android:lStar="97" />
+ <item android:color="@color/system_neutral1_500" android:lStar="98" />
</selector>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 72cbc8f643f8..b6a598488776 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"toegang tot jou fisieke aktiwiteit"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"foto\'s en video te neem"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Bluetooth-toestelle in die omtrek"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"ontdek en koppel aan Bluetooth-toestelle in die omtrek"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Toestelle in die omtrek"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"ontdek en koppel aan toestelle in die omtrek"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Oproeprekords"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"lees en skryf foonoproeprekord"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Foon"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Laat die program toe om Bluetooth-toestelle in die omtrek te ontdek en saam te bind"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"koppel aan saamgebinde Bluetooth-toestelle"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Laat die program toe om aan saamgebinde Bluetooth-toestelle te koppel"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"adverteer op Bluetooth-toestelle in die omtrek"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Laat die program toe om op Bluetooth-toestelle in die omtrek te adverteer"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"bepaal relatiewe posisie tussen ultrabreëbandtoestelle in die omtrek"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Laat die program toe om relatiewe posisie tussen ultrabreëbandtoestelle in die omtrek te bepaal"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Voorkeur-NFC-betalingdiensinligting"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Laat die program toe om voorkeur-NFC-betalingdiensinligting soos geregistreerde hulpmiddels en roetebestemming te kry."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"beheer kortveldkommunikasie"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Jy kan nou \'n deel van jou skerm vergroot"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Skakel aan in Instellings"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Maak toe"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Skakel aan"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Deblokkeer toestelmikrofoon"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Deblokkeer toestelkamera"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Vir &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; en alle programme en dienste"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Deblokkeer"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorprivaatheid"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Programikoon"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Programhandelsmerkprent"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 0256ab1e6910..e96f50527946 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"የእርስዎን አካላዊ እንቅስቃሴ ይድረሱበት"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"ካሜራ"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ስዕሎች ያንሱ እና ቪዲዮ ይቅረጹ"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"በአቅራቢያ ያሉ የብሉቱዝ መሣሪያዎች"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"በአቅራቢያ ያሉ የብሉቱዝ መሣሪያዎችን ያግኙ እና ያገናኙ"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"በአቅራቢያ ያሉ መሣሪያዎች"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"በአቅራቢያ ያሉ መሣሪያዎችን ያሉበትን ያግኙ እና ያገናኙ"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"የጥሪ ምዝገባ ማስታወሻዎች"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"የስልክ ጥሪ ምዝግባ ማስታወሻን ያንብቡ እና ይጻፉ"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ስልክ"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"መተግበሪያው በአቅራቢያ ያሉ የብሉቱዝ መሣሪያዎችን እንዲያገኝ እና እንዲጣመር ይፈቅድለታል"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ከተጣመሩ የብሉቱዝ መሣሪያዎች ጋር ያገናኙ"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"መተግበሪያው ከተጣመሩ የብሉቱዝ መሣሪያዎች ጋር እንዲገናኝ ይፈቅድለታል"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"በአቅራቢያ ላሉ የብሉቱዝ መሣሪያዎችን ያስተዋውቁ"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"በአቅራቢያ ላሉ የብሉቱዝ መሣሪያዎችን እንዲያስተዋውቅ መተግበሪያው ያስችለዋል"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"በአቅራቢያ ባሉ ልዕለ ሰፊ ባንድ መሣሪያዎች መካከል ተዛማጅ የሆነውን ቦታ ይወቁ"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"በአቅራቢያ ባሉ ልዕለ-ሰፊ ባንድ መሣሪያዎች መካከል ያለውን አንጻራዊ አቀማመጣቸውን ለማወቅ ንዲችል ለመተግበሪያው ይፍቀዱ"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ተመራጭ NFC የክፍያ አገልግሎት መረጃ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"እንደ የተመዘገቡ እርዳታዎች እና የጉዞ መሥመር መዳረሻ የመሳሰለ ተመራጭ nfc የክፍያ አገልግሎት መረጃን ለማግኘት ለመተግበሪያው ያፈቅድለታል።"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ቅርብ የግኑኙነትመስክ (NFC) ተቆጣጠር"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"አሁን የማያ ገጽዎን ክፍል ማጉላት ይችላሉ"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"በቅንብሮች ውስጥ ያብሩ"</string>
<string name="dismiss_action" msgid="1728820550388704784">"አሰናብት"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ለመቀጠል፣ &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ወደ መሳሪያዎ ማይክሮፎን መድረስ ይፈልጋል።"</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"ለመቀጠል፣ &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; የመሣሪያዎን ካሜራ መድረስ ይፈልጋል።"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"አብራ"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"የመሣሪያ ማይክሮፎን እገዳን አንሳ"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"የመሣሪያ ካሜራ እገዳን አንሳ"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"ለ&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; እና ሁሉም መተግበሪያዎች እና አገልግሎቶች"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"እገዳውን አንሳ"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ዳሳሽ ግላዊነት"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"የመተግበሪያ አዶ"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"የመተግበሪያ የምርት ስም ምስል"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index c8acfc0b5639..c68aeababbe5 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -331,8 +331,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"الوصول إلى بيانات نشاطك البدني"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"الكاميرا"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"التقاط صور وتسجيل فيديو"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"الأجهزة القريبة التي تتضمّن بلوتوث"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"تسمح هذه الأذونات للتطبيق باكتشاف الأجهزة القريبة التي تتضمّن بلوتوث والربط بها."</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"الأجهزة المجاورة"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"يسمح هذا الإذن برصد الأجهزة المجاورة والربط بها."</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"سجلّ المكالمات"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"قراءة سجلّ المكالمات الهاتفية والكتابة إليه"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"الهاتف"</string>
@@ -550,10 +550,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"يسمح هذا الإذن للتطبيق باكتشاف الأجهزة القريبة التي تتضمّن بلوتوث والاقتران بها."</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"تسمح بالربط الأجهزة المقترنة التي تتضمّن بلوتوث."</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"يسمح هذا الإذن للتطبيق بالارتباط بالأجهزة المقترنة التي تتضمّن بلوتوث."</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"تحديد الموضع النسبي بين الأجهزة المجاورة التي تستخدم النطاق الواسع جدًا"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"يسمح هذا الإذن للتطبيق بتحديد الموضع النسبي بين الأجهزة المجاورة التي تستخدم النطاق الواسع جدًا."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏معلومات الخدمات المدفوعة باستخدام الاتصال قصير المدى NFC المفضّل"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏يسمح هذا الإذن للتطبيق بالحصول على معلومات الخدمات المدفوعة باستخدام الاتصال قصير المدى NFC المفضّل، مثلاً المساعدات المسجّلة ووجهة المسار."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"التحكم في اتصال الحقل القريب"</string>
@@ -2395,9 +2397,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"يمكنك الآن تكبير جزء من الشاشة."</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"التفعيل من خلال \"الإعدادات\""</string>
<string name="dismiss_action" msgid="1728820550388704784">"إغلاق"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"‏للمتابعة، يحتاج &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; إلى الوصول إلى ميكروفون الجهاز."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"‏للمتابعة، يحتاج تطبيق &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; إلى الوصول إلى كاميرا الجهاز."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"تفعيل"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"الخصوصية في جهاز الاستشعار"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"رمز التطبيق"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"الصورة الذهنية للعلامة التجارية للتطبيق"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 5b65daa0c2a6..9718df6252c6 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -319,8 +319,10 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"শাৰীৰিক কাৰ্যকলাপ এক্সেছ কৰা"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"কেমেৰা"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ফট\' তুলিব আৰু ভিডিঅ\' ৰেকৰ্ড কৰিব পাৰে"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"নিকটৱৰ্তী ব্লুটুথ ডিভাইচ"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"নিকটৱৰ্তী ব্লুটুথ ডিভাইচ বিচাৰি উলিয়াওক আৰু সেইসমূহৰ সৈতে সংযোগ কৰক"</string>
+ <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
+ <skip />
<string name="permgrouplab_calllog" msgid="7926834372073550288">"কল লগসমূহ"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ফ\'নৰ কল লগ পঢ়ক আৰু লিখক"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ফ’ন"</string>
@@ -538,6 +540,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"এপ্‌টোক নিকটৱৰ্তী ব্লুটুথ ডিভাইচ বিচাৰি উলিয়াবলৈ আৰু সেইসমূহৰ সৈতে পেয়াৰ কৰিবলৈ অনুমতি দিয়ে"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"পেয়াৰ কৰা ব্লুটুথ ডিভাইচৰ সৈতে সংযোগ কৰক"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"এপ্‌টোক পেয়াৰ কৰা ব্লুটুথ ডিভাইচৰ সৈতে সংযোগ কৰিবলৈ অনুমতি দিয়ে"</string>
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
+ <skip />
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
+ <skip />
<!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
<skip />
<!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
@@ -2259,9 +2265,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"আপুনি এতিয়া আপোনাৰ স্ক্ৰীনখনৰ কিছু অংশ বিবৰ্ধন কৰিব পাৰে"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ছেটিঙত অন কৰক"</string>
<string name="dismiss_action" msgid="1728820550388704784">"অগ্ৰাহ্য কৰক"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"অব্যাহত ৰাখিবলৈ &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;এ আপোনাৰ ডিভাইচৰ মাইক্ৰ’ফ’ন এক্সেছ কৰাৰ আৱশ্যক।"</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"অব্যাহত ৰাখিবলৈ &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;এ আপোনাৰ ডিভাইচৰ কেমেৰা এক্সেছ কৰাৰ আৱশ্যক।"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"অন কৰক"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ছেন্সৰ সম্পৰ্কীয় গোপনীয়তাৰ নীতি"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"এপ্লিকেশ্বনৰ চিহ্ন"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"এপ্লিকেশ্বনৰ ব্ৰেণ্ডৰ প্ৰতিচ্ছবি"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index da7da277ef5f..e0ea700efaac 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"fiziki fəaliyyətə daxil olun"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"şəkil çəkin və video yazın"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"yaxınlıqdakı Bluetooth cihazları"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"yaxınlıqdakı Bluetooth cihazlarını aşkarlamaq və onlara qoşulmaq"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Yaxınlıqdakı cihazlar"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"yaxınlıqdakı cihazları tapmaq və qoşulmaq"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Zəng qeydləri"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"telefonun zəng qeydini oxuyun və yazın"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Tətbiqə yaxınlıqdakı Bluetooth cihazlarını aşkarlamaq və birləşdirməyə icazə verir"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"birləşdirilmiş Bluetooth cihazlarına qoşulmaq"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Tətbiqə birləşdirilmiş Bluetooth cihazlarına qoşulmağa icazə verir"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"yaxınlıqdakı Ultra Genişzolaqlı cihazları arasında nisbi mövqeyi təyin etmək"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Tətbiqə yaxınlıqdakı Ultra Genişzolaqlı cihazları arasında nisbi mövqeyi təyin etməyə icazə verin"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Tərcih edilən NFC ödəniş xidməti məlumatı"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Tətbiqə qeydiyyatdan keçmiş yardım və marşrut təyinatı kimi tərcih edilən nfc ödəniş xidməti məlumatını əldə etmək icazəsi verir."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication\'ı kontrol et"</string>
@@ -1016,7 +1018,7 @@
<string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"Tətbiqə Brauzerin geolokasiya icazələrini dəyişməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək məkan məlumatlarını təsadüfi saytlara göndərə bilər."</string>
<string name="save_password_message" msgid="2146409467245462965">"Brauzerin bu şifrəni yadda saxlamasını istəyirsiz?"</string>
<string name="save_password_notnow" msgid="2878327088951240061">"İndi yox"</string>
- <string name="save_password_remember" msgid="6490888932657708341">"Yadda saxla"</string>
+ <string name="save_password_remember" msgid="6490888932657708341">"Yadda saxlayın"</string>
<string name="save_password_never" msgid="6776808375903410659">"Heç vaxt"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"Bu səhifəni açmaq üçün icazəniz yoxdur."</string>
<string name="text_copied" msgid="2531420577879738860">"Mətn panoya kopyalandı."</string>
@@ -1358,7 +1360,7 @@
<string name="usb_supplying_notification_title" msgid="5378546632408101811">"USB vasitəsilə qoşulmuş cihaza enerji doldurulur"</string>
<string name="usb_mtp_notification_title" msgid="1065989144124499810">"USB fayl transferi aktiv edildi"</string>
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB vasitəsilə PTP aktiv edildi"</string>
- <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB birləşmə aktiv edildi"</string>
+ <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB-modem aktivdir"</string>
<string name="usb_midi_notification_title" msgid="7404506788950595557">"USB vasitəsilə MIDI aktiv edildi"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB aksesuarı qoşulub"</string>
<string name="usb_notification_message" msgid="4715163067192110676">"Əlavə seçimlər üçün tıklayın."</string>
@@ -1624,7 +1626,7 @@
<string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Ekranı cihaza yayımla"</string>
<string name="media_route_chooser_searching" msgid="6119673534251329535">"Cihazlar axtarılır..."</string>
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Ayarlar"</string>
- <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Bağlantını kəs"</string>
+ <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Əlaqəni kəsin"</string>
<string name="media_route_status_scanning" msgid="8045156315309594482">"Skan edilir..."</string>
<string name="media_route_status_connecting" msgid="5845597961412010540">"Qoşulur..."</string>
<string name="media_route_status_available" msgid="1477537663492007608">"Əlçatımlı"</string>
@@ -1854,8 +1856,8 @@
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"Batareyanın ömrünü artırmaq üçün Enerjiyə Qənaət funksiyası:\n\n• Qaranlıq temanı aktiv edir\n• Arxa fondakı fəaliyyəti, bəzi vizual effektləri və “Hey Google” kimi digər funksiyaları deaktiv edir və ya məhdudlaşdırır\n\n"<annotation id="url">"Ətraflı məlumat"</annotation></string>
<string name="battery_saver_description" msgid="6794188153647295212">"Batareyanın ömrünü artırmaq üçün Enerjiyə Qənaət funksiyası:\n\n• Qaranlıq temanı aktiv edir\n• Arxa fondakı fəaliyyəti, bəzi vizual effektləri və “Hey Google” kimi digər funksiyaları deaktiv edir və ya məhdudlaşdırır"</string>
- <string name="data_saver_description" msgid="4995164271550590517">"Data istifadəsini azalatmaq üçün, Data Qanaəti bəzi tətbiqlərin arxafonda data göndərməsinin və qəbulunun qarşısını alır. Hazırda işlətdiyiniz tətbiq dataya daxil ola bilər, ancaq bunu tez-tez edə bilməz. Bu o deməkdir ki, məsələn, Siz üzərinə tıklamadıqca o şəkillər göstərilməyəcək."</string>
- <string name="data_saver_enable_title" msgid="7080620065745260137">"Data Qənaəti aktiv edilsin?"</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"Mobil interneti qənaətlə işlətmək məqsədilə Data Qanaəti bəzi tətbiqlərin fonda data göndərməsinin və qəbulunun qarşısını alır. Hazırda işlətdiyiniz tətbiq nisbətən az müntəzəmliklə data istifadə edə bilər. Örnək olaraq bu, o deməkdir ki, şəkil fayllarına toxunmadıqca onlar açılmayacaq."</string>
+ <string name="data_saver_enable_title" msgid="7080620065745260137">"Trafikə qənaət edilsin?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Aktivləşdirin"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
<item quantity="other"> %1$d dəqiqəlik (saat <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> radəsinə qədər)</item>
@@ -1892,7 +1894,7 @@
<string name="zen_mode_until_next_day" msgid="1403042784161725038">"Bu vaxtadək: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_until" msgid="2250286190237669079">"Saat <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> qədər"</string>
<string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> radəsinə qədər (növbəti siqnal)"</string>
- <string name="zen_mode_forever" msgid="740585666364912448">"Deaktiv edənə qədər"</string>
+ <string name="zen_mode_forever" msgid="740585666364912448">"Deaktiv edilənə qədər"</string>
<string name="zen_mode_forever_dnd" msgid="3423201955704180067">"\"Narahat etməyin\" seçiminini deaktiv edənə kimi"</string>
<string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="8009920446193610996">"Dağıt"</string>
@@ -1901,7 +1903,7 @@
<string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Həftəiçi gecəsi"</string>
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Həftə sonu"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Tədbir"</string>
- <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Yuxu"</string>
+ <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Yuxu vaxtı"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> bəzi səsləri səssiz rejimə salır"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Cihazınızın daxili problemi var və istehsalçı sıfırlanması olmayana qədər qeyri-stabil ola bilər."</string>
<string name="system_error_manufacturer" msgid="703545241070116315">"Cihazınızın daxili problemi var. Əlavə məlumat üçün istehsalçı ilə əlaqə saxlayın."</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"İndi ekranınızın bir hissəsini böyüdə bilərsiniz"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ayarlarda aktiv edin"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Qapadın"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aktiv edin"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor Məxfiliyi"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Tətbiq ikonası"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Tətbiqin brend şəkli"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 81ca4e6030a0..f9b24b7a434d 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -322,8 +322,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"pristup fizičkim aktivnostima"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"snima slike i video"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Bluetooth uređaji u blizini"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"otkrivanje i povezivanje sa Bluetooth uređajima u blizini"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Uređaji u blizini"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"otkrivanje uređaja u blizini i povezivanje sa njima"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Evidencije poziva"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"čitanje i pisanje evidencije poziva na telefonu"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -541,10 +541,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Dozvoljava aplikaciji da otkriva Bluetooth uređaje u blizini i uparuje se sa njima"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"povezivanje sa uparenim Bluetooth uređajima"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Dozvoljava aplikaciji da se povezuje sa uparenim Bluetooth uređajima"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"oglašavanje na Bluetooth uređajima u blizini"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Dozvoljava aplikaciji da se oglašava na Bluetooth uređajima u blizini"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"određivanje razdaljine između uređaja ultra-širokog pojasa u blizini"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Dozvoljava aplikaciji da određuje relativnu razdaljinu između uređaja ultra-širokog pojasa u blizini"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacije o željenoj NFC usluzi za plaćanje"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Dozvoljava aplikaciji da preuzima informacije o željenoj NFC usluzi za plaćanje, poput registrovanih identifikatora aplikacija i odredišta preusmeravanja."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrola komunikacije u užem polju (Near Field Communication)"</string>
@@ -2293,9 +2293,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Sada možete da uvećate deo ekrana"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Uključite u Podešavanjima"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Odbaci"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"&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_notification_content" msgid="4738005643315863736">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; zahteva pristup kameri uređaja radi nastavljanja."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Uključi"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Odblokirajte mikrofon uređaja"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Odblokirajte kameru uređaja"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Za &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; i sve aplikacije i usluge"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Odblokiraj"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privatnost senzora"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikacije"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imidž brenda aplikacije"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 995bf8e3987c..24172d9d193f 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -325,8 +325,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"доступ да даных фізічнай актыўнасці"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Камера"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"рабіць фатаздымкі і запісваць відэа"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Прылады з Bluetooth паблізу"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"выяўляць прылады з Bluetooth, якія знаходзяцца паблізу, і падключацца да іх"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Прылады паблізу"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"выяўляць прылады паблізу і падключацца да іх"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Журналы выклікаў"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"Чытанне і запіс журнала тэлефонных выклікаў"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Тэлефон"</string>
@@ -544,10 +544,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Дазваляе праграме выяўляць прылады з Bluetooth і спалучацца з імі"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"падключацца да спалучаных прылад з Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Дазваляе праграме падключацца да спалучаных прылад з Bluetooth"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"вызначаць адлегласць паміж прыладамі з звышшырокапалоснай сувяззю"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Дазволіць праграме вызначаць адлегласць паміж прыладамі паблізу, якія выкарыстоўваюць звышшырокапалосную сувязь"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Інфармацыя пра прыярытэтны сэрвіс аплаты NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дазваляе праграме атрымаць доступ да інфармацыі пра прыярытэтны сэрвіс аплаты NFC, напрыклад зарэгістраваныя ідэнтыфікатары праграм і маршруты адпраўкі даных."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"кантроль Near Field Communication"</string>
@@ -1406,8 +1408,8 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Выяўлены аксесуар аналагавага аўдыя"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Далучаная прылада не сумяшчальная з гэтым тэлефонам. Націсніце, каб даведацца больш."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"Адладка па USB падключана"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"Націсніце, каб выключыць адладку па USB"</string>
- <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Выберыце, каб адключыць адладку USB."</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"Націсніце, каб адключыць адладку па USB"</string>
+ <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Выберыце, каб адключыць адладку па USB."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Адладка па Wi-Fi уключана"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Націсніце, каб выключыць адладку па Wi-Fi"</string>
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Выберыце, каб выключыць адладку па Wi-Fi."</string>
@@ -2054,7 +2056,7 @@
<string name="app_category_productivity" msgid="1844422703029557883">"Прадукцыйнасць"</string>
<string name="app_category_accessibility" msgid="6643521607848547683">"Спецыяльныя магчымасці"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Сховішча на прыладзе"</string>
- <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Адладка USB"</string>
+ <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Адладка па USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"гадз"</string>
<string name="time_picker_minute_label" msgid="8307452311269824553">"хв"</string>
<string name="time_picker_header_text" msgid="9073802285051516688">"Задаць час"</string>
@@ -2327,9 +2329,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Цяпер можна павялічваць частку экрана"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Уключыць у Наладах"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Адхіліць"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Каб працягнуць, дайце праграме &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; доступ да мікрафона прылады."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Каб працягнуць, дайце праграме &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; доступ да камеры прылады."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Уключыць"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Прыватнасць інфармацыі з датчыка"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Значок праграмы"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Відарыс брэнда праграмы"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 61f1c24c1565..2d5a8851ab69 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"достъп до физическата ви активност"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Камера"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"да прави снимки и записва видео"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Устройства с Bluetooth в близост"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"откриване на устройства с Bluetooth в близост и свързване с тях"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Устройства в близост"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"откриване на устройства в близост и свързване с тях"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Списъци с обажданията"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"четене и запис на списъка с телефонните обаждания"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Телефон"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Дава възможност на приложението да открива устройства с Bluetooth в близост и да се сдвоява с тях"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"свързване със сдвоените устройства с Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Дава възможност на приложението да се свързва със сдвоените устройства с Bluetooth"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"рекламиране на устройства с Bluetooth в близост"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Разрешава на приложението да рекламира на устройства с Bluetooth в близост"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"опред. на относителната позиция м/у у-вата с ултрашироколентови сигнали в близост"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Разрешаване на приложението да определя относителната позиция между устройствата с ултрашироколентови сигнали в близост"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информация за предпочитаната услуга за плащане чрез NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дава възможност на приложението да получава информация за предпочитаната услуга за плащане чрез NFC, като например регистрирани помощни средства и местоназначение."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"контролиране на комуникацията в близкото поле"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Вече можете да увеличите част от екрана"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Включете от настройките"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Отхвърляне"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"За да продължите, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; се нуждае от достъп до микрофона на устройството ви."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"За да продължите, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; се нуждае от достъп до камерата на устройството ви."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Включване"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Отблокиране на микрофона на устройството"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Отблокиране на камерата на устройството"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"За &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; и всички приложения и услуги"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Отблокиране"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Поверителност на сензорните данни"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Икона на приложението"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Изображение на търговската марка на приложението"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index b279b3b10549..cffa00e05473 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -319,8 +319,10 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"শারীরিক অ্যাক্টিভিটি অ্যাক্সেস করা"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"ক্যামেরা"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ছবি তোলা এবং ভিডিও রেকর্ড"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"কাছাকাছি ব্লুটুথ ডিভাইস"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"কাছাকাছি ব্লুটুথ ডিভাইস খুঁজে দেখুন এবং তার সাথে কানেক্ট করুন"</string>
+ <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
+ <skip />
<string name="permgrouplab_calllog" msgid="7926834372073550288">"কল লগ"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ফোন কল লগ পড়ে এবং দেখে"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ফোন"</string>
@@ -538,6 +540,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"অ্যাপটিকে কাছাকাছি ব্লুটুথ ডিভাইস খুঁজে দেখতে এবং তার সাথে পেয়ার করার অনুমতি দেয়"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"পেয়ার করা ব্লুটুথ ডিভাইসের সাথে কানেক্ট করুন"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"অ্যাপটিকে পেয়ার করা ব্লুটুথ ডিভাইসের সাথে কানেক্ট করতে অনুমতি দেয়"</string>
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
+ <skip />
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
+ <skip />
<!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
<skip />
<!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
@@ -1624,7 +1630,7 @@
<string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"ডিভাইসে স্ক্রিন কাস্ট করুন"</string>
<string name="media_route_chooser_searching" msgid="6119673534251329535">"ডিভাইসগুলি সার্চ করা হচ্ছে…"</string>
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"সেটিংস"</string>
- <string name="media_route_controller_disconnect" msgid="7362617572732576959">"সংযোগ বিচ্ছিন্ন করুন"</string>
+ <string name="media_route_controller_disconnect" msgid="7362617572732576959">"ডিসকানেক্ট করুন"</string>
<string name="media_route_status_scanning" msgid="8045156315309594482">"স্ক্যান করা হচ্ছে…"</string>
<string name="media_route_status_connecting" msgid="5845597961412010540">"সংযুক্ত হচ্ছে..."</string>
<string name="media_route_status_available" msgid="1477537663492007608">"উপলব্ধ"</string>
@@ -2259,9 +2265,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"আপনার স্ক্রিনের অংশ এখন আপনি বড় করে দেখতে পারবেন"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"সেটিংস থেকে চালু করুন"</string>
<string name="dismiss_action" msgid="1728820550388704784">"বাতিল করুন"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"চালিয়ে যেতে, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; আপনার ডিভাইসের মাইক্রোফোন অ্যাক্সেস করতে চায়।"</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"চালিয়ে যেতে, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; আপনার ডিভাইসের ক্যামেরা অ্যাক্সেস করতে চায়।"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"চালু করুন"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"সেন্সর গোপনীয়তা"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"অ্যাপের আইকন"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"অ্যাপের ব্র্যান্ড ছবি"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 0dac1b936800..5ab3aa16cd8c 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -322,8 +322,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"pristup vašoj fizičkoj aktivnosti"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"snima fotografije i videozapise"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Bluetooth uređaji u blizini"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"otkrivanje Bluetooth uređaja u blizini i povezivanje s njima"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Uređaji u blizini"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"otkrivanje uređaja u blizini i povezivanje s njima"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Zapisnici poziva"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"čitanje i pisanje zapisnika telefonskih poziva"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -541,10 +541,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Dozvoljava aplikaciji da otkrije Bluetooth uređaje u blizini i upari se s njima"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"povezivanje s uparenim Bluetooth uređajima"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Dozvoljava aplikaciji da se poveže s uparenim Bluetooth uređajima"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"oglašavanje na Bluetooth uređajima u blizini"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Aplikaciji omogućuje oglašavanje na Bluetooth uređajima u blizini"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"određivanje rel. položaja uređaja ultra širokog opsega u blizini"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Dozvolite aplikaciji da odredi relativni položaj između uređaja ultra širokog opsega u blizini"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacije o preferiranoj usluzi plaćanja putem NFC-a"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Dozvoljava aplikaciji da dobije informacije o preferiranoj usluzi plaćanja putem NFC-a kao što su registrirana pomagala i odredište rute."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"upravljanje NFC-om"</string>
@@ -1354,10 +1354,10 @@
<string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Uvijek dozvoli"</string>
<string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"Nikada ne dozvoli"</string>
<string name="sim_removed_title" msgid="5387212933992546283">"SIM kartica uklonjena"</string>
- <string name="sim_removed_message" msgid="9051174064474904617">"Mobilna mreža bit će nedostupna do ponovnog pokretanja s umetnutom važećom SIM karticom."</string>
+ <string name="sim_removed_message" msgid="9051174064474904617">"Mobilna mreža neće biti dostupna dok ponovo ne pokrenete uređaj s umetnutom važećom SIM karticom."</string>
<string name="sim_done_button" msgid="6464250841528410598">"Gotovo"</string>
<string name="sim_added_title" msgid="7930779986759414595">"SIM kartica dodana"</string>
- <string name="sim_added_message" msgid="6602906609509958680">"Za pristup mobilnoj mreži ponovo pokrenite uređaj."</string>
+ <string name="sim_added_message" msgid="6602906609509958680">"Ponovo pokrenite uređaj da pristupite mobilnoj mreži."</string>
<string name="sim_restart_button" msgid="8481803851341190038">"Ponovo pokreni"</string>
<string name="install_carrier_app_notification_title" msgid="5712723402213090102">"Aktivirajte uslugu mobilne mreže"</string>
<string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Preuzmite aplikaciju operatera da aktivirate novi SIM"</string>
@@ -1405,7 +1405,7 @@
<string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"Vaš administrator je zatražio izvještaj o greškama kako bi pomogao u rješavanju problema ovog uređaja. Moguće je dijeljenje aplikacija i podataka."</string>
<string name="share_remote_bugreport_action" msgid="7630880678785123682">"PODIJELI"</string>
<string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ODBACI"</string>
- <string name="select_input_method" msgid="3971267998568587025">"Odabir načina unosa"</string>
+ <string name="select_input_method" msgid="3971267998568587025">"Odaberite način unosa"</string>
<string name="show_ime" msgid="6406112007347443383">"Prikaži na ekranu dok je fizička tastatura aktivna"</string>
<string name="hardware" msgid="1800597768237606953">"Prikaz virtuelne tastature"</string>
<string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Konfiguriraj fizičku tastaturu"</string>
@@ -2293,9 +2293,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Sada možete uvećati dio ekrana"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Uključite u Postavkama"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Odbaci"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Da nastavite, aplikaciji &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; je potreban pristup mikrofonu vašeg uređaja."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Da nastavite, aplikaciji &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; je potreban pristup kameri vašeg uređaja."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Uključi"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Deblokiraj mikrofon uređaja"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Deblokiraj fotoaparat uređaja"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Za &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; i sve aplikacije i usluge"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Deblokiraj"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privatnost senzora"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikacije"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Slika robne marke za aplikaciju"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 3d1ff857ab32..da02b0bd2c80 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"accedir a la teva activitat física"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Càmera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"fer fotos i gravar vídeos"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Dispositius Bluetooth propers"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"detectar i connectar-se a dispositius Bluetooth propers"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Dispositius propers"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"detectar dispositius propers i connectar-s\'hi"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Registres de trucades"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"llegir i editar el registre de trucades del telèfon"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telèfon"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permet que l\'aplicació detecti i vinculi dispositius Bluetooth propers"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"connectar-se a dispositius Bluetooth vinculats"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permet que l\'aplicació es connecti a dispositius Bluetooth vinculats"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"anunciar-se als dispositius Bluetooth propers"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permet que l\'aplicació s\'anunciï als dispositius Bluetooth propers"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"determinar posició entre dispositius de banda ultraampla propers"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permet que l\'aplicació determini la posició relativa entre els dispositius de banda ultraampla propers"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informació preferent sobre el servei de pagament per NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet que l\'aplicació obtingui informació preferent sobre el servei de pagament per NFC, com ara complements registrats i destinacions de rutes."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar Comunicació de camp proper (NFC)"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Ara pots ampliar una part de la pantalla"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activa a Configuració"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Ignora"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Activa"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Desbloqueja el micròfon del dispositiu"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Desbloqueja la càmera del dispositiu"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Per a &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; i tots els serveis i aplicacions"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Desbloqueja"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privadesa dels sensors"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icona d\'aplicació"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imatge de brànding de l\'aplicació"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 70ad32619362..3a25a8ab459e 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -325,8 +325,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"přístup k vaší fyzické aktivitě"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Fotoaparát"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"pořizování fotografií a nahrávání videa"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Zařízení Bluetooth v okolí"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"vyhledávat zařízení Bluetooth v okolí a připojovat se k nim"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Zařízení v okolí"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"objevování a připojení k zařízením v okolí"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Seznamy hovorů"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"čtení a zápis do seznamu telefonních hovorů"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -544,10 +544,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Umožňuje aplikaci vyhledávat zařízení Bluetooth v okolí a spárovávat se s nimi"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"připojovat se ke spárovaným zařízením Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Umožňuje aplikaci připojovat se ke spárovaným zařízením Bluetooth"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"inzerovat zařízením Bluetooth v okolí"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Umožňuje aplikaci inzerovat zařízením Bluetooth v okolí"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"zjišťování vzájemné pozice mezi ultra-širokopásmovými zařízeními v okolí"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Aplikace bude moci zjišťovat vzájemnou pozici mezi ultra-širokopásmovými zařízeními v okolí"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informace o preferované platební službě NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Umožňuje aplikaci získat informace o preferované platební službě NFC, například o registrovaných pomůckách a cíli směrování."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ovládání technologie NFC"</string>
@@ -1954,7 +1954,7 @@
<string name="zen_mode_until_next_day" msgid="1403042784161725038">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_until" msgid="2250286190237669079">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_alarm" msgid="7046911727540499275">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (příští budík)"</string>
- <string name="zen_mode_forever" msgid="740585666364912448">"Dokud tuto funkci nevypnete"</string>
+ <string name="zen_mode_forever" msgid="740585666364912448">"Dokud funkci nevypnete"</string>
<string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Dokud nevypnete režim Nerušit"</string>
<string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="8009920446193610996">"Sbalit"</string>
@@ -2327,9 +2327,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Nově můžete zvětšit část obrazovky"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Zapnout v Nastavení"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Zavřít"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Zapnout"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Odblokovat mikrofon zařízení"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Odblokovat fotoaparát zařízení"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Pro aplikaci &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; a všechny aplikace a služby"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Odblokovat"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Ochrana soukromí – senzor"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikace"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Image značky aplikace"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index c4db344c13e1..4561a4094da0 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"få adgang til din fysiske aktivitet"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"tage billeder og optage video"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Bluetooth-enheder i nærheden"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"registrer og opret forbindelse til Bluetooth-enheder i nærheden"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Enheder i nærheden"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"finde og oprette forbindelse til enheder i nærheder"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Opkaldslister"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"læse og redigere opkaldslisten"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -540,10 +540,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Tillader, at appen registrerer og parrer Bluetooth-enheder i nærheden"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"opret forbindelse til parrede Bluetooth-enheder"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Tillader, at appen opretter forbindelse til parrede Bluetooth-enheder"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"give sig til kende for Bluetooth-enheder i nærheden"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Giver appen tilladelse til at give sig til kende for Bluetooth-enheder i nærheden"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"fastlægge den relative position mellem UWB-enheder i nærheden"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Tillad, at appen fastlægger den relative position mellem UWB-enheder (Ultra-Wideband) i nærheden"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Foretrukne oplysninger vedrørende NFC-betalingstjeneste"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Tillader, at appen får foretrukne oplysninger vedrørende NFC-betalingstjeneste, f.eks. registrerede hjælpemidler og rutedestinationer."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"administrere Near Field Communication"</string>
@@ -2261,9 +2261,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Du kan nu forstørre noget af skærmen"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktivér i Indstillinger"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Luk"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"&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_notification_content" msgid="4738005643315863736">"&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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aktivér"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Fjern blokeringen af enhedens mikrofon"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Fjern blokeringen af enhedens kamera"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"For &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; og alle apps og tjenester"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Fjern blokering"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Beskyttelse af sensoroplysninger"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Appens ikon"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Appens brandimage"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index d98ea9992b23..cb46d91d99c9 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -319,8 +319,10 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"Zugriff auf körperliche Aktivität"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"Bilder und Videos aufnehmen"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Bluetooth-Geräte in der Nähe"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"Bluetooth-Geräte in der Nähe finden und eine Verbindung zu ihnen herstellen"</string>
+ <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
+ <skip />
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Anrufliste"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"Schreib- und Lesezugriff auf Anrufliste"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -538,6 +540,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Erlaubt der App, Bluetooth-Geräte in der Nähe zu finden und zu koppeln"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"Mit gekoppelten Bluetooth-Geräten verbinden"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Erlaubt der App, sich mit gekoppelten Bluetooth-Geräten zu verbinden"</string>
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
+ <skip />
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
+ <skip />
<!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
<skip />
<!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
@@ -715,8 +721,8 @@
<string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Ermöglicht dem Inhaber die Bindung an die Oberfläche eines Mobilfunkanbieter-Messaging-Dienstes auf oberster Ebene. Für normale Apps sollte dies nie erforderlich sein."</string>
<string name="permlab_bindCarrierServices" msgid="2395596978626237474">"An Mobilfunkanbieter-Dienste binden"</string>
<string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Ermöglicht dem Inhaber die Bindung an Mobilfunkanbieter-Dienste. Für normale Apps sollte dies nicht erforderlich sein."</string>
- <string name="permlab_access_notification_policy" msgid="5524112842876975537">"Auf \"Bitte nicht stören\" zugreifen"</string>
- <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Ermöglicht der App Lese- und Schreibzugriff auf die \"Bitte nicht stören\"-Konfiguration"</string>
+ <string name="permlab_access_notification_policy" msgid="5524112842876975537">"Auf „Bitte nicht stören“ zugreifen"</string>
+ <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Ermöglicht der App Lese- und Schreibzugriff auf die „Bitte nicht stören“-Konfiguration"</string>
<string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"Mit der Verwendung der Anzeigeberechtigung beginnen"</string>
<string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Ermöglicht dem Inhaber, die Berechtigungsnutzung für eine App zu beginnen. Sollte für normale Apps nie benötigt werden."</string>
<string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"Sensordaten mit hoher Frequenz auslesen"</string>
@@ -1893,7 +1899,7 @@
<string name="zen_mode_until" msgid="2250286190237669079">"Bis <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_alarm" msgid="7046911727540499275">"Bis <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (nächste Weckzeit)"</string>
<string name="zen_mode_forever" msgid="740585666364912448">"Bis zur Deaktivierung"</string>
- <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Bis zur Deaktivierung von \"Bitte nicht stören\""</string>
+ <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Bis zur Deaktivierung von „Bitte nicht stören“"</string>
<string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="8009920446193610996">"Minimieren"</string>
<string name="zen_mode_feature_name" msgid="3785547207263754500">"Bitte nicht stören"</string>
@@ -2058,9 +2064,9 @@
<string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Anrufe und Benachrichtigungen stummgeschaltet"</string>
<string name="notification_channel_system_changes" msgid="2462010596920209678">"Systemänderungen"</string>
<string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Bitte nicht stören"</string>
- <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Neu: Durch \"Bitte nicht stören\" werden Benachrichtigungen nicht mehr angezeigt"</string>
+ <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Neu: Durch „Bitte nicht stören“ werden Benachrichtigungen nicht mehr angezeigt"</string>
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Für weitere Informationen und zum Ändern tippen."</string>
- <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\"Bitte nicht stören\" wurde geändert"</string>
+ <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"„Bitte nicht stören“ wurde geändert"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tippe, um zu überprüfen, welche Inhalte blockiert werden."</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Einstellungen"</string>
@@ -2259,9 +2265,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Du kannst das Display teilweise vergrößern"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"In den Einstellungen aktivieren"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Schließen"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aktivieren"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Datenschutz für Sensoren"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"App-Symbol"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"App-Branding-Hintergrundbild"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index fffa6af4b187..9cb6c24bdbb1 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"πρόσβαση στη σωματική σας δραστηριότητα"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Κάμερα"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"γίνεται λήψη φωτογραφιών και εγγραφή βίντεο"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Κοντινές συσκευές Bluetooth"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"ανακάλυψη και σύνδεση σε κοντινές συσκευές Bluetooth"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Συσκευές σε κοντινή απόσταση"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"ανακάλυψη και σύνδεση σε κοντινές συσκευές"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Αρχεία καταγρ. κλήσ."</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ανάγνωση και εγγραφή αρχείου καταγραφής τηλεφωνικών κλήσεων"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Τηλέφωνο"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Επιτρέπει στην εφαρμογή την ανακάλυψη και τη σύζευξη κοντινών συσκευών Bluetooth"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"σύνδεση σε συζευγμένες συσκευές Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Επιτρέπει στην εφαρμογή τη σύνδεση σε συζευγμένες συσκευές Bluetooth"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"προβολή διαφημίσεων σε κοντινές συσκευές Bluetooth"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Επιτρέπει στην εφαρμογή να προβάλλει διαφημίσεις σε κοντινές συσκευές Bluetooth"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"προσδιορισμός σχετ. θέσης μεταξύ κοντινών συσκευών Ultra-Wideband"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Επιτρέψτε στην εφαρμογή να προσδιορίζει τη σχετική θέση μεταξύ κοντινών συσκευών Ultra-Wideband"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Πληροφορίες προτιμώμενης υπηρεσίας πληρωμών NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Επιτρέπει στην εφαρμογή να λαμβάνει πληροφορίες προτιμώμενης υπηρεσίας πληρωμής NFC, όπως καταχωρημένα βοηθήματα και προορισμό διαδρομής."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ελέγχει την Επικοινωνία κοντινού πεδίου (FNC)"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Μπορείτε πλέον να μεγεθύνετε μέρος της οθόνης σας"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ενεργοποίηση στις Ρυθμίσεις"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Παράβλεψη"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Για να συνεχίσετε, η εφαρμογή &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; χρειάζεται πρόσβαση στο μικρόφωνο της συσκευής σας."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Για να συνεχίσετε, η εφαρμογή &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; χρειάζεται πρόσβαση στην κάμερα της συσκευής σας."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Ενεργοποίηση"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Κατάργηση αποκλεισμού μικροφώνου συσκευής"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Κατάργηση αποκλεισμού κάμερας συσκευής"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Για την εφαρμογή &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; και όλες τις εφαρμογές και υπηρεσίες"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Κατάργηση αποκλεισμού"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Απόρρητο αισθητήρα"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Εικονίδιο εφαρμογής"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Εικόνα επωνυμίας εφαρμογής"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index afa48b9b73ad..72c59e000a17 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"access your physical activity"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Camera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"take pictures and record video"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Nearby Bluetooth devices"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"discover and connect to nearby Bluetooth devices"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Nearby devices"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"discover and connect to nearby devices"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Call logs"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"read and write phone call logs"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Phone"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Allows the app to discover and pair nearby Bluetooth devices"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"connect to paired Bluetooth devices"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Allows the app to connect to paired Bluetooth devices"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"advertise to nearby Bluetooth devices"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Allows the app to advertise to nearby Bluetooth devices"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"determine relative position between nearby ultra-wideband devices"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Allow the app to determine relative position between nearby ultra-wideband devices"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"You can now magnify part of your screen"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Turn on in settings"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Dismiss"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"To continue, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; needs access to your device microphone."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"To continue, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; needs access to your device’s camera."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Turn on"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Unblock device microphone"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Unblock device camera"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"For &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; and all apps and services"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Unblock"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor privacy"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Application icon"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Application branding image"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 7f0078177bf8..03c500767425 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"access your physical activity"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Camera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"take pictures and record video"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Nearby Bluetooth devices"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"discover and connect to nearby Bluetooth devices"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Nearby devices"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"discover and connect to nearby devices"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Call logs"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"read and write phone call logs"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Phone"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Allows the app to discover and pair nearby Bluetooth devices"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"connect to paired Bluetooth devices"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Allows the app to connect to paired Bluetooth devices"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"advertise to nearby Bluetooth devices"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Allows the app to advertise to nearby Bluetooth devices"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"determine relative position between nearby ultra-wideband devices"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Allow the app to determine relative position between nearby ultra-wideband devices"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"You can now magnify part of your screen"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Turn on in settings"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Dismiss"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"To continue, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; needs access to your device microphone."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"To continue, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; needs access to your device’s camera."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Turn on"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Unblock device microphone"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Unblock device camera"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"For &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; and all apps and services"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Unblock"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor privacy"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Application icon"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Application branding image"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 42a9bb08794f..f52de960b3da 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"access your physical activity"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Camera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"take pictures and record video"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Nearby Bluetooth devices"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"discover and connect to nearby Bluetooth devices"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Nearby devices"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"discover and connect to nearby devices"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Call logs"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"read and write phone call logs"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Phone"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Allows the app to discover and pair nearby Bluetooth devices"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"connect to paired Bluetooth devices"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Allows the app to connect to paired Bluetooth devices"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"advertise to nearby Bluetooth devices"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Allows the app to advertise to nearby Bluetooth devices"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"determine relative position between nearby ultra-wideband devices"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Allow the app to determine relative position between nearby ultra-wideband devices"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"You can now magnify part of your screen"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Turn on in settings"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Dismiss"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"To continue, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; needs access to your device microphone."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"To continue, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; needs access to your device’s camera."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Turn on"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Unblock device microphone"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Unblock device camera"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"For &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; and all apps and services"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Unblock"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor privacy"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Application icon"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Application branding image"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 7a6833a8b7a7..4e770bf8dace 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"access your physical activity"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Camera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"take pictures and record video"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Nearby Bluetooth devices"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"discover and connect to nearby Bluetooth devices"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Nearby devices"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"discover and connect to nearby devices"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Call logs"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"read and write phone call logs"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Phone"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Allows the app to discover and pair nearby Bluetooth devices"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"connect to paired Bluetooth devices"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Allows the app to connect to paired Bluetooth devices"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"advertise to nearby Bluetooth devices"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Allows the app to advertise to nearby Bluetooth devices"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"determine relative position between nearby ultra-wideband devices"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Allow the app to determine relative position between nearby ultra-wideband devices"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"You can now magnify part of your screen"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Turn on in settings"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Dismiss"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"To continue, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; needs access to your device microphone."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"To continue, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; needs access to your device’s camera."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Turn on"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Unblock device microphone"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Unblock device camera"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"For &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; and all apps and services"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Unblock"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor privacy"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Application icon"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Application branding image"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 2da3b95414a8..e9959c03601b 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‎‏‎‏‎‎‏‏‎‎‏‎‏‎‏‎‏‏‏‏‎‎‎‏‏‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‏‏‏‏‏‎‎‎‏‏‎‎‎‎‎access your physical activity‎‏‎‎‏‎"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‎‏‎‏‎‏‎‎‎‏‎‏‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎‎Camera‎‏‎‎‏‎"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‎‏‎‎‎‎‏‎‏‎‎‏‎‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎take pictures and record video‎‏‎‎‏‎"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‎‎‏‎‎‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‎‎‏‎‏‎‎‏‎‏‎‎‏‏‏‎‏‎‏‏‎Nearby Bluetooth Devices‎‏‎‎‏‎"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‎discover and connect to nearby Bluetooth devices‎‏‎‎‏‎"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‎‏‏‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‏‎‎‏‎‏‏‎‏‎‎‏‏‏‎Nearby devices‎‏‎‎‏‎"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎discover and connect to nearby devices‎‏‎‎‏‎"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‎‎‏‏‏‏‏‏‎‎‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‎‎‎‎‎Call logs‎‏‎‎‏‎"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‏‎‏‏‏‏‏‎‏‎‎‏‎‏‏‎read and write phone call log‎‏‎‎‏‎"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‎‏‏‎‏‎‏‏‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‎‎‎‏‎‏‏‏‎‎‎Phone‎‏‎‎‏‎"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‎‏‏‎‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎Allows the app to discover and pair nearby Bluetooth devices‎‏‎‎‏‎"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‎‎‎‏‎‎‎‏‎‎‎‎connect to paired Bluetooth devices‎‏‎‎‏‎"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‎‎‎‎‏‎‏‎‎‏‎Allows the app to connect to paired Bluetooth devices‎‏‎‎‏‎"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‏‎‎‏‎advertise to nearby Bluetooth devices‎‏‎‎‏‎"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎Allows the app to advertise to nearby Bluetooth devices‎‏‎‎‏‎"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎determine relative position between nearby Ultra-Wideband devices‎‏‎‎‏‎"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‎‎‎‎‎‏‎‎‎‎‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‏‏‏‏‎Allow the app to determine relative position between nearby Ultra-Wideband devices‎‏‎‎‏‎"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‎‎‏‎‎‎‏‎‏‎‏‎‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎Preferred NFC Payment Service Information‎‏‎‎‏‎"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‏‎‏‏‏‎Allows the app to get preferred nfc payment service information like registered aids and route destination.‎‏‎‎‏‎"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‎‏‎control Near Field Communication‎‏‎‎‏‎"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‏‏‎‏‏‏‏‏‎‎‎‎‏‏‎‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‎‏‏‎You can now magnify part of your screen‎‏‎‎‏‎"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‎‎‏‏‎‎‏‎‏‎‏‎‎‎Turn on in Settings‎‏‎‎‏‎"</string>
<string name="dismiss_action" msgid="1728820550388704784">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎‎‎‎‏‎‎‎‎‎Dismiss‎‏‎‎‏‎"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‎‏‎‎‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‎To continue, &lt;b&gt;‎‏‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt; needs access to your device microphone.‎‏‎‎‏‎"</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎To continue, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt; needs access to your device’s camera.‎‏‎‎‏‎"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‎Turn on‎‏‎‎‏‎"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‎‎‎‏‏‎‏‏‎‏‏‏‏‏‏‎Unblock device microphone‎‏‎‎‏‎"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‎Unblock device camera‎‏‎‎‏‎"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‏‎‎For &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt; and all apps and services‎‏‎‎‏‎"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‎‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‎Unblock‎‏‎‎‏‎"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‏‎‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎Sensor Privacy‎‏‎‎‏‎"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‏‎‎‎‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎Application icon‎‏‎‎‏‎"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎Application branding image‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index c511484f0ea5..8534cae34659 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"acceder a tu actividad física"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Cámara"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"tomar fotografías y grabar videos"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Dispositivos Bluetooth cercanos"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"Descubre dispositivos Bluetooth cercanos y conéctate a ellos"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Dispositivos cercanos"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"descubrir y conectarse a dispositivos cercanos"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Llamadas"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"leer y escribir el registro de llamadas telefónicas"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Teléfono"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que la app descubra dispositivos Bluetooth cercanos y se conecte a ellos"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"conectarse a dispositivos Bluetooth vinculados"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite que la app se conecte a dispositivos Bluetooth vinculados"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"determinar posición entre disposit. Ultra Wideband"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite que la app determine la posición relativa con dispositivos Ultra Wideband cercanos"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información sobre servicio de pago NFC preferido"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que la app reciba información del servicio de pago NFC preferido, como el servicio de asistencia registrado y el destino de la ruta."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar la Transmisión de datos en proximidad"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Ahora puedes ampliar parte de la pantalla"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activar en Configuración"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Descartar"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Para continuar, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&amp;gt necesita acceso al micrófono del dispositivo."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Para continuar, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&amp;gt necesita acceso a la cámara del dispositivo."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Activar"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidad del sensor"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ícono de la aplicación"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imagen de marca de la aplicación"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 7a9971a449ec..eb046bf25f84 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"acceder a tu actividad física"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Cámara"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"hacer fotos y grabar vídeos"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Dispositivos Bluetooth cercanos"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"detecta y conéctate a dispositivos Bluetooth cercanos"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Dispositivos cercanos"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"detectar y conectarse a dispositivos cercanos"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Registros de llamadas"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"leer y escribir en el registro de llamadas del teléfono"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Teléfono"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que la aplicación detecte y vincule dispositivos Bluetooth cercanos"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"conectarse a dispositivos Bluetooth vinculados"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite que la aplicación se conecte a dispositivos Bluetooth vinculados"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"mostrar anuncios a dispositivos Bluetooth cercanos"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite que la aplicación muestre anuncios a dispositivos Bluetooth cercanos"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"calcular posición de dispositivos de banda ultraancha cercanos"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite que la aplicación determine la posición relativa de los dispositivos de banda ultraancha cercanos"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información sobre el servicio de pago por NFC preferido"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que la aplicación obtenga información sobre el servicio de pago por NFC preferido, como identificadores de aplicación registrados y destinos de rutas."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar Comunicación de campo cercano (NFC)"</string>
@@ -1386,7 +1386,7 @@
<string name="share_remote_bugreport_action" msgid="7630880678785123682">"COMPARTIR"</string>
<string name="decline_remote_bugreport_action" msgid="4040894777519784346">"RECHAZAR"</string>
<string name="select_input_method" msgid="3971267998568587025">"Selecciona un método de entrada"</string>
- <string name="show_ime" msgid="6406112007347443383">"Lo mantiene en pantalla mientras el teclado físico está activo"</string>
+ <string name="show_ime" msgid="6406112007347443383">"Mientras el teclado físico está activo"</string>
<string name="hardware" msgid="1800597768237606953">"Mostrar teclado virtual"</string>
<string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Configura el teclado físico"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Toca para seleccionar el idioma y el diseño"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Ahora puedes ampliar una parte de la pantalla"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activar en Ajustes"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Cerrar"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Activar"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Desbloquea el micrófono del dispositivo"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Desbloquea la cámara del dispositivo"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Para que &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; y todos los servicios y las aplicaciones puedan acceder"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Desbloquear"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidad del sensor"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icono de aplicación"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imagen de marca de aplicación"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 17e3364fa72e..91d9f726e6be 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"juurdepääs teie füüsilisele tegevusele"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kaamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"pildistamine ja video salvestamine"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Lähedalasuvad Bluetooth-seadmed"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"lähedalasuvate Bluetooth-seadmete avastamine ja nendega ühenduse loomine"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Lähedalasuvad seadmed"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"Avastada lähedalasuvaid seadmeid ja luua nendega ühenduse."</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Kõnelogid"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"telefoni kõnelogi lugemine ja kirjutamine"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Lubab rakendusel avastada lähedalasuvaid Bluetooth-seadmeid ja nendega siduda"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"seotud Bluetooth-seadmetega ühenduse loomine"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Lubab rakendusel luua ühenduse seotud Bluetooth-seadmetega"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"lähedalolevatele Bluetooth-seadmetele reklaamimine"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Lubab rakendusel läheduses olevatele Bluetooth-seadmetele reklaamida"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"Määrata lähedalasuvate ülilairibaühendust kasutavate seadmete suhtelise kauguse üksteisest."</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Võimaldab rakendusel määrata lähedalasuvate ülilairibaühendust kasutavate seadmete suhtelise kauguse üksteisest"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Eelistatud NFC-makseteenuse teave"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Võimaldab rakendusel hankida eelistatud NFC-makseteenuse teavet (nt registreeritud abi ja marsruudi sihtkoht)."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"lähiväljaside juhtimine"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Saate nüüd suurendada osa oma ekraanikuvast"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Lülitage sisse menüüs Seaded"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Loobu"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Lülita sisse"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Tühistage seadme mikrofoni blokeerimine"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Tühistage seadme kaamera blokeerimine"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Rakenduse &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ja kõikide rakenduste ning teenuste puhul"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Tühista blokeerimine"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Anduri privaatsus"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Rakenduse ikoon"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Rakenduse brändi kujutis"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index e04dcbb8c1a5..d97033783fc4 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"jarduera fisikoa atzitu"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"atera argazkiak eta grabatu bideoak"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Inguruko Bluetooth bidezko gailuak"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"inguruko Bluetooth bidezko gailuak hauteman eta haietara konektatu"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Inguruko gailuak"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"inguruko gailuak hauteman eta haietara konektatu"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Deien erregistroa"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"irakurri telefonoko deien erregistroa eta idatzi bertan"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefonoa"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Inguruko Bluetooth bidezko gailuak hautemateko eta haiekin parekatzeko baimena ematen die aplikazioei"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"parekatutako Bluetooth bidezko gailuetara konektatu"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Parekatutako Bluetooth bidezko gailuetara konektatzeko baimena ematen die aplikazioei"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"inguruko Bluetooth bidezko gailuei publizitatea erakutsi"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Inguruko Bluetooth bidezko gailuei publizitatea erakusteko baimena ematen die aplikazioei"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"banda ultrazabala darabilten inguruko gailuen arteko distantzia erlatiboa zehaztu"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Banda ultrazabala darabilten inguruko gailuen arteko distantzia erlatiboa zehazteko baimena ematen die aplikazioei"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC bidezko ordainketa-zerbitzu lehenetsiari buruzko informazioa"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Aplikazioari baimena ematen dio NFC bidezko ordainketa-zerbitzu lehenetsiari buruzko informazioa jasotzeko, hala nola erregistratutako laguntzaileak eta ibilbidearen helmuga."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolatu Near Field Communication komunikazioa"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Orain, pantailaren zati bat handi dezakezu"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktibatu ezarpenetan"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Baztertu"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aktibatu"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Desblokeatu gailuaren mikrofonoa"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Desblokeatu gailuaren kamera"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; aplikazioak eta aplikazio eta zerbitzu guztiek erabili ahal izateko"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Desblokeatu"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sentsoreen pribatutasuna"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Aplikazioaren ikonoa"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Aplikazioaren marka-irudia"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index c693c2465026..64b56efe51f3 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"دسترسی به فعالیت فیزیکی شما"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"دوربین"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"عکس گرفتن و فیلم‌برداری"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"دستگاه‌های بلوتوث اطراف"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"پیدا کردن دستگاه‌های بلوتوث اطراف و اتصال به آن‌ها"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"دستگاه‌های اطراف"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"پیدا کردن دستگاه‌های اطراف و متصل شدن به آن‌ها"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"گزارش‌های تماس"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"خواندن و نوشتن گزارش تماس تلفنی"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"تلفن"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"به برنامه اجازه می‌دهد دستگاه‌های بلوتوث اطراف را پیدا کند و با آن‌ها مرتبط شود"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"اتصال به دستگاه‌های بلوتوث مرتبط‌شده"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"به برنامه اجازه می‌دهد به دستگاه‌های بلوتوث مرتبط‌شده متصل شود"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"تبلیغ در دستگاه‌های بلوتوث اطراف"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"برنامه مجاز می‌شود در دستگاه‌های بلوتوث اطراف تبلیغ کند."</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"مشخص کردن موقعیت نسبی بین دستگاه‌های باند فوق‌وسیع اطراف"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"به برنامه اجازه داده می‌شود موقعیت نسبی بین دستگاه‌های باند فوق‌وسیع اطراف را مشخص کند"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏اطلاعات ترجیحی سرویس پولی «ارتباط میدان نزدیک» (NFC)"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏به برنامه اجازه می‌دهد اطلاعات ترجیحی سرویس پولی «ارتباط میدان نزدیک» (NFC)، مانند کمک‌های ثبت‌شده و مقصد مسیر را دریافت کند."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"کنترل ارتباط راه نزدیک"</string>
@@ -1854,7 +1854,7 @@
<string name="confirm_battery_saver" msgid="5247976246208245754">"تأیید"</string>
<string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"‏برای افزایش عمر باتری، «بهینه‌سازی باتری»:\n\n• «طرح زمینه تیره» را روشن می‌کند\n• فعالیت پس‌زمینه، برخی جلوه‌های بصری، و دیگر ویژگی‌ها مانند «Ok Google» را خاموش یا محدود می‌کند\n\n"<annotation id="url">"بیشتر بدانید"</annotation></string>
<string name="battery_saver_description" msgid="6794188153647295212">"‏برای افزایش عمر باتری، «بهینه‌سازی باتری»:\n\n• «طرح زمینه تیره» را روشن می‌کند\n• فعالیت پس‌زمینه، برخی جلوه‌های بصری، و دیگر ویژگی‌ها مثل «Ok Google» را خاموش یا محدود می‌کند"</string>
- <string name="data_saver_description" msgid="4995164271550590517">"«صرفه‌جویی داده»، برای کمک به کاهش مصرف داده، از ارسال و دریافت داده در پس‌زمینه ازطرف بعضی برنامه‌ها جلوگیری می‌کند. برنامه‌ای که درحال‌حاضر استفاده می‌کنید می‌تواند به داده‌ها دسترسی داشته باشد اما دفعات دسترسی آن محدود است.این یعنی، برای مثال، تصاویر تازمانی‌که روی آن‌ها ضربه نزنید نشان داده نمی‌شوند."</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"برای کمک به کاهش مصرف داده، «صرفه‌جویی داده» از ارسال و دریافت داده در پس‌زمینه در بعضی برنامه‌ها جلوگیری می‌کند. برنامه‌ای که درحال‌حاضر استفاده می‌کنید می‌تواند به داده‌ها دسترسی داشته باشد اما دفعات دسترسی آن محدود است. این می‌تواند به این معنی باشد که، برای مثال، تصاویر تازمانی‌که روی آن‌ها ضربه نزنید نشان داده نمی‌شوند."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"«صرفه‌جویی داده» روشن شود؟"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"روشن کردن"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"اکنون می‌توانید بخشی از صفحه را درشت‌نمایی کنید"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"روشن کردن در «تنظیمات»"</string>
<string name="dismiss_action" msgid="1728820550388704784">"رد شدن"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"‏برای ادامه دادن، &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; باید به میکروفون دستگاه دسترسی داشته باشد."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"‏برای ادامه دادن، &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; باید به دوربین دستگاه دسترسی داشته باشد."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"روشن کردن"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"لغو انسداد میکروفون دستگاه"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"لغو انسداد دوربین دستگاه"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"‏برای &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; و همه برنامه‌ها و سرویس‌ها"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"لغو انسداد"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"حریم‌خصوصی حسگر"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"نماد برنامه"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"تصویر نمانام‌سازی برنامه"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 232883bd95b7..1c8929563e2b 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"nähdä liikkumistietosi"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ottaa kuvia ja videoita"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Lähellä olevat Bluetooth-laitteet"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"löytää lähellä olevia Bluetooth-laitteita ja yhdistää niihin"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Lähellä olevat laitteet"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"löytää lähellä olevia laitteita ja yhdistää niihin"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Puhelulokit"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"lukea puhelulokia ja kirjoittaa siihen"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Puhelin"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Sallii sovelluksen löytää lähellä olevia Bluetooth-laitteita ja muodostaa niistä laitepareja"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"yhdistää pariliitettyihin Bluetooth-laitteisiin"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Sallii sovelluksen muodostaa yhteyden pariliitettyihin Bluetooth-laitteisiin"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"määrittää UVB:ta käyttävien laitteiden suhteellisen sijainnin"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Sallii sovelluksen määrittää UVB-taajuutta käyttävien laitteiden sijainnin suhteessa toisiinsa"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Ensisijaiset NFC-maksupalvelutiedot"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Sallii sovelluksen noutaa tietoja rekisteröidyistä sovellustunnuksista, maksureitin kohteesta ja muita ensisijaisia NFC-maksupalvelutietoja."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"hallitse Near Field Communication -tunnistusta"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Voit nyt suurentaa näytön osan"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Laita päälle asetuksista"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Hylkää"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"Jotta voit jatkaa, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; tarvitsee pääsyn laitteesi kameraan."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Laita päälle"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Anturin tietosuoja"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Sovelluskuvake"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Sovelluksen tuotemerkkikuva"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index b03b22765f5c..0f595257a166 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"accéder à vos activités physiques"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Appareil photo"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"prendre des photos et filmer des vidéos"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Appareils Bluetooth à proximité"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"découvrir les appareils Bluetooth à proximité et s\'y connecter"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Appareils à proximité"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"découvrir les appareils à proximité et s\'y connecter"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Journaux d\'appels"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"lire et écrire le journal des appels téléphoniques"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Téléphone"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permet à l\'application de découvrir les appareils Bluetooth à proximité et de s\'y connecter"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"se connecter aux appareils Bluetooth associés"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permet à l\'application de se connecter aux appareils Bluetooth associés"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"déterminer la position relative entre des appareils à bande ultralarge à proximité"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Autorisez l\'application à déterminer la position relative entre des appareils à bande ultralarge à proximité"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Information sur le service préféré de paiement NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet à l\'application d\'obtenir de l\'information sur le service préféré de paiement NFC comme les aides enregistrées et la route de destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"gérer la communication en champ proche"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Vous pouvez agrandir une partie votre écran."</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activer dans les paramètres"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Fermer"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Pour continuer, vous devez accorder l\'accès au microphone de votre appareil à l\'application &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Pour continuer, vous devez accorder l\'accès à l\'appareil photo de votre appareil à l\'application &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Activer"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Confidentialité des capteurs"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icône de l\'application"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Image de marque de l\'application"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index ff3cdf8701e7..444cfeda1ad4 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"accéder aux données d\'activité physique"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Appareil photo"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"prendre des photos et enregistrer des vidéos"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Appareils Bluetooth à proximité"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"détecter les appareils Bluetooth à proximité et s\'y connecter"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Appareils à proximité"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"détecter des appareils à proximité et s\'y connecter"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Journaux d\'appels"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"Consulter et modifier les journaux d\'appels du téléphone"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Téléphone"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Autorise l\'appli à détecter et à associer les appareils Bluetooth à proximité"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"se connecter aux appareils Bluetooth associés"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Autorise l\'appli à se connecter à des appareils Bluetooth associés"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"déterminer position relative entre appareils ultra-wideband à proximité"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Autoriser l\'appli à déterminer la position relative entre des appareils ultra-wideband à proximité"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informations sur le service de paiement NFC préféré"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet à l\'application d\'obtenir des informations sur le service de paiement NFC préféré, y compris les ID d\'applications et les destinations de routage enregistrés."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"contrôler la communication en champ proche"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Vous pouvez désormais agrandir une partie de l\'écran"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activer dans les paramètres"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Fermer"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Activer"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Confidentialité du capteur"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icône de l\'application"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Image de branding de l\'application"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 425e76ba06b6..caa4c03d7619 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"acceder á túa actividade física"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Cámara"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"tirar fotos e gravar vídeos"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Dispositivos Bluetooth próximos"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"detectar dispositivos Bluetooth próximos e conectarse a eles"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Dispositivos próximos"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"detectar dispositivos próximos e conectarse a eles"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Rexistros de chamadas"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ler e editar o rexistro de chamadas do teléfono"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Teléfono"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que a aplicación detecte dispositivos Bluetooth próximos e se vincule a eles"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"conectarse a dispositivos Bluetooth vinculados"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite que a aplicación se conecte aos dispositivos Bluetooth vinculados"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"determinar posición entre dispositivos próximos"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite que a aplicación determine a posición relativa entre os dispositivos próximos que usen banda ultralarga"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información do servizo de pago de NFC preferido"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que a aplicación obteña información do servizo de pago de NFC preferido, como as axudas rexistradas e o destino da ruta."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar Near Field Communication"</string>
@@ -1854,7 +1856,7 @@
<string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string>
<string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"Para aumentar a duración da batería, a función Aforro de batería fai o seguinte:\n\n• Activa o tema escuro.\n• Desactiva ou restrinxe a actividade en segundo plano, algúns efectos visuais e outras funcións, como \"Ok Google\".\n\n"<annotation id="url">"Máis información"</annotation></string>
<string name="battery_saver_description" msgid="6794188153647295212">"Para aumentar a duración da batería, a función Aforro de batería fai o seguinte:\n\n• Activa o tema escuro\n• Desactiva ou restrinxe a actividade en segundo plano, algúns efectos visuais e outras funcións, como \"Ok Google\""</string>
- <string name="data_saver_description" msgid="4995164271550590517">"Para contribuír a reducir o uso de datos, o aforro de datos impide que algunhas aplicacións envíen ou reciban datos en segundo plano. Cando esteas utilizando unha aplicación, esta poderá acceder aos datos, pero é posible que o faga con menos frecuencia. Por exemplo, é posible que as imaxes non se mostren ata que as toques."</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"Para contribuír a reducir o uso de datos, o aforro de datos impide que algunhas aplicacións envíen ou reciban datos en segundo plano. Cando esteas utilizando unha aplicación, esta poderá acceder aos datos, pero é posible que o faga con menos frecuencia. Por exemplo, poida que as imaxes non se mostren ata que as toques."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Queres activar o aforro de datos?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Activar"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Xa podes ampliar parte da pantalla"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activar en Configuración"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Ignorar"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"Para continuar, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; precisa acceder á cámara do dispositivo."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Activar"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidade do sensor"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icona de aplicación"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imaxe de marca da aplicación"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 956a39c5175d..30603912694a 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -319,8 +319,10 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"તમારી શારીરિક પ્રવૃત્તિને ઍક્સેસ કરવી"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"કૅમેરા"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ચિત્રો લેવાની અને વીડિઓ રેકોર્ડ કરવાની"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"આસપાસના બ્લૂટૂથ ડિવાઇસ"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"આસપાસના બ્લૂટૂથ ડિવાઇસ શોધો અને તેમની સાથે કનેક્ટ કરો"</string>
+ <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
+ <skip />
<string name="permgrouplab_calllog" msgid="7926834372073550288">"કૉલ લૉગ"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ફોન કૉલ લૉગ વાંચો અને લખો"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ફોન"</string>
@@ -538,6 +540,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ઍપને આસપાસના બ્લૂટૂથ ડિવાઇસ શોધવાની અને તેની સાથે જોડી કરવાની મંજૂરી આપે છે"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"જોડી કરેલા બ્લૂટૂથ ડિવાઇસ સાથે કનેક્ટ કરો"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ઍપને જોડી કરેલા બ્લૂટૂથ ડિવાઇસ સાથે કનેક્ટ કરવાની મંજૂરી આપે છે"</string>
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
+ <skip />
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
+ <skip />
<!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
<skip />
<!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
@@ -1606,7 +1612,7 @@
<string name="sending" msgid="206925243621664438">"મોકલી રહ્યાં છે…"</string>
<string name="launchBrowserDefault" msgid="6328349989932924119">"બ્રાઉઝર લોન્ચ કરીએ?"</string>
<string name="SetupCallDefault" msgid="5581740063237175247">"કૉલ સ્વીકારીએ?"</string>
- <string name="activity_resolver_use_always" msgid="5575222334666843269">"હંમેશા"</string>
+ <string name="activity_resolver_use_always" msgid="5575222334666843269">"હંમેશાં"</string>
<string name="activity_resolver_use_once" msgid="948462794469672658">"ફક્ત એક વાર"</string>
<string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s કાર્ય પ્રોફાઇલનું સમર્થન કરતું નથી"</string>
<string name="default_audio_route_name" product="tablet" msgid="367936735632195517">"ટેબ્લેટ"</string>
@@ -2259,9 +2265,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"હવે તમે તમારી સ્ક્રીનનો અમુક ભાગ મોટો કરી શકો છો"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"સેટિંગમાં ચાલુ કરો"</string>
<string name="dismiss_action" msgid="1728820550388704784">"છોડી દો"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ચાલુ રાખવા માટે, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;ને તમારા ડિવાઇસના માઇક્રોફોનના ઍક્સેસની જરૂર છે."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"ચાલુ રાખવા માટે, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;ને તમારા ડિવાઇસના કૅમેરાના ઍક્સેસની જરૂર છે."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ચાલુ કરો"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"સેન્સર પ્રાઇવસી સંબંધિત નોટિફિકેશન"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ઍપ્લિકેશનનું આઇકન"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ઍપ્લિકેશનની બ્રાંડિંગ છબી"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index e01465b229ac..65eb10bfc9e7 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"शारीरिक गतिविधि की जानकारी पा सकता है"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"कैमरा"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"चित्र लेने और वीडियो रिकॉर्ड करने"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"आस-पास मौजूद ब्लूटूथ डिवाइस"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"आस-पास मौजूद ब्लूटूथ डिवाइसों को खोजें और उनसे कनेक्ट करें"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"आस-पास मौजूद डिवाइस"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"आस-पास मौजूद डिवाइस खोजें और उनसे कनेक्ट करें"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"कॉल लॉग"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"कॉल लॉग की जानकारी देखना और उसमें बदलाव करना"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"फ़ोन"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"अनुमति देने पर, ऐप्लिकेशन, आस-पास मौजूद ब्लूटूथ डिवाइसों को खोज पाएगा और उनसे जुड़ पाएगा"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"जोड़े गए ब्लूटूथ डिवाइसों से कनेक्ट करें"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"अनुमति देने पर, ऐप्लिकेशन, जोड़े गए ब्लूटूथ डिवाइसों से कनेक्ट कर पाएगा"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"आस-पास मौजूद Ultra-Wideband डिवाइसों के बीच की दूरी का पता लगाएं"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ऐप्लिकेशन को आस-पास मौजूद Ultra-Wideband डिवाइसों के बीच की दूरी का पता लगाने की अनुमति दें"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC का इस्तेमाल करने वाली पैसे चुकाने की पसंदीदा सेवा की जानकारी"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"अगर ऐप्लिकेशन को अनुमति दी जाती है, तो वह पैसे चुकाने की आपकी उस पसंदीदा सेवा के बारे में जानकारी पा सकता है जो NFC का इस्तेमाल करती है. इसमें रजिस्टर किए गए डिवाइस और उनके आउटपुट के रूट जैसी जानकारी शामिल होती है."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"नियर फ़ील्‍ड कम्‍यूनिकेशन नियंत्रित करें"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"अब आप अपनी स्क्रीन के किसी हिस्से को ज़ूम करके देख सकते हैं"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"सेटिंग में जाकर, इस सुविधा को चालू करें"</string>
<string name="dismiss_action" msgid="1728820550388704784">"खारिज करें"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"जारी रखने के लिए, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; को आपके डिवाइस का माइक्रोफ़ोन ऐक्सेस करने की ज़रूरत है."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"जारी रखने के लिए, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; को आपके डिवाइस का कैमरा ऐक्सेस करने की ज़रूरत है."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"चालू करें"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"सेंसर से जुड़ी निजता के बारे में सूचना"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ऐप्लिकेशन का आइकॉन"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ऐप्लिकेशन की ब्रैंड इमेज"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 3e90a6338ba4..093257f6d221 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -322,8 +322,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"pristupiti vašoj tjelesnoj aktivnosti"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Fotoaparat"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"snimati fotografije i videozapise"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Bluetooth uređaji u blizini"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"otkriti Bluetooth uređaje u blizini i povezati se s njima"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Uređaji u blizini"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"otkrivanje i povezivanje s uređajima u blizini"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Zapisnici poziva"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"čitati i pisati zapisnik poziva telefona"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -541,10 +541,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Aplikaciji omogućuje otkrivanje i uparivanje Bluetooth uređaja u blizini"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"povezati se s uparenim Bluetooth uređajima"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Aplikaciji omogućuje povezivanje s uparenim Bluetooth uređajima"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"oglašavanje na Bluetooth uređajima u blizini"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Aplikaciji omogućuje oglašavanje na Bluetooth uređajima u blizini"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"odredite približni položaj između uređaja u blizini koji upotrebljavaju ultraširokopojasno povezivanje"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Dopušta aplikaciji da odredi približni položaj između uređaja u blizini koji upotrebljavaju ultraširokopojasno povezivanje"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacije o preferiranoj usluzi plaćanja NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Omogućuje aplikaciji primanje informacija o preferiranoj usluzi plaćanja NFC kao što su registrirana pomagala i odredište."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"upravljanje beskontaktnom komunikacijom (NFC)"</string>
@@ -2293,9 +2293,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Sad možete povećati dio zaslona"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Uključite u Postavkama"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Odbaci"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Uključi"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Deblokiraj mikrofon uređaja"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Deblokiraj fotoaparat uređaja"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Za &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; i sve aplikacije i usluge"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Deblokiraj"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privatnost senzora"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikacije"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imidž robne marke aplikacije"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 9e61a2f9c84e..ed421736c6d8 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"hozzáférés a testmozgási adatokhoz"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"fotók és videók készítése"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Közeli Bluetooth-eszközök"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"közeli Bluetooth-eszközök felfedezése és csatlakozás hozzájuk"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Közeli eszközök"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"közeli eszközök felfedezése, és csatlakozás hozzájuk"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Hívásnaplók"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"hívásnapló olvasása és írása"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Lehetővé teszi az alkalmazás számára a közeli Bluetooth-eszközök felfedezését és a velük való párosítást."</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"csatlakozás párosított Bluetooth-eszközökhöz"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Lehetővé teszi az alkalmazás számára a párosított Bluetooth-eszközökhöz való csatlakozást."</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"közzététel a közeli Bluetooth-eszközök számára"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Lehetővé teszi az alkalmazás számára, hogy közzétegye jelenlétét a közeli Bluetooth-eszközök számára"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"közeli, ultraszélessávú eszközök közötti relatív pozíció meghatározása"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Az alkalmazás meghatározhatja a közeli, ultraszélessávú eszközök közötti relatív pozíciót"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferált NFC fizetési szolgáltatási információk"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Lehetővé teszi az alkalmazás számára preferált NFC fizetési szolgáltatási információk (pl. regisztrált alkalmazásazonosítók és útvonali cél) lekérését."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC technológia vezérlése"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Mostantól kinagyíthatja a képernyő egy részét"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Bekapcsolás a Beállításokban"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Elvetés"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Bekapcsolás"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Az eszközmikrofon letiltásának feloldása"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Az eszközkamera letiltásának feloldása"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"A(z) &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;, valamint az összes alkalmazás és szolgáltatás esetében"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Tiltásfeloldás"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Érzékelőkkel kapcsolatos adatvédelem"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Alkalmazás ikonja"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Alkalmazás márkaképe"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 5b14f3f02483..1f0f351c8366 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"հասանելիություն ֆիզիկական ակտիվությանը"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Տեսախցիկ"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"լուսանկարել և տեսագրել"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Մոտակա Bluetooth սարքեր"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"հայտնաբերել մոտակա Bluetooth սարքերը և միանալ դրանց"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Մոտակա սարքեր"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"հայտնաբերել մոտակա սարքերը և միանալ դրանց"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Զանգերի մատյան"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"հեռախոսազանգերի մատյանի դիտում և գրանցում"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Հեռախոս"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Թույլ է տալիս հավելվածին հայտնաբերել և զուգակցել մոտակա Bluetooth սարքերը"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"միանալ զուգակցված Bluetooth սարքերի"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Թույլ է տալիս հավելվածին միանալ զուգակցված Bluetooth սարքերի"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"որոշել մոտակա UWB սարքերի միջև հարաբերական դիրքավորումը"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Թույլատրել հավելվածին որոշել գերլայնաշերտ կապի տեխնոլոգիան աջակցող մոտակա սարքերի միջև հարաբերական դիրքավորումը"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Տեղեկություններ NFC վճարային ծառայության մասին"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Թույլ է տալիս հավելվածին ստանալ նախընտրելի NFC վճարային ծառայության մասին տեղեկություններ (օր․՝ գրանցված լրացուցիչ սարքերի և երթուղու նպատակակետի մասին տվյալներ)։"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"վերահսկել Մոտ Տարածությամբ Հաղորդակցումը"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Դուք կարող եք խոշորացնել ձեր էկրանի մի մասը"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Միացնել կարգավորումներում"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Փակել"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Շարունակելու համար &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; հավելվածին անհրաժեշտ է սարքի խոսափողի օգտագործման թույլտվություն։"</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Շարունակելու համար &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; հավելվածին անհրաժեշտ է ձեր սարքի տեսախցիկի օգտագործման թույլտվություն։"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Միացնել"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Տվիչների գաղտնիություն"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Հավելվածի պատկերակ"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Հավելվածի բրենդային պատկեր"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 587437155d8d..1c55fb83bd4b 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"mengakses aktivitas fisik Anda"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"mengambil gambar dan merekam video"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Perangkat Bluetooth di Sekitar"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"temukan dan hubungkan ke perangkat Bluetooth di sekitar"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Perangkat di sekitar"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"menemukan dan terhubung ke perangkat di sekitar"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Log panggilan"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"membaca dan menulis log panggilan telepon"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telepon"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Mengizinkan aplikasi menemukan dan menyambungkan perangkat Bluetooth di sekitar"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"hubungkan ke perangkat Bluetooth yang disambungkan"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Mengizinkan aplikasi terhubung ke perangkat Bluetooth yang disambungkan"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"menentukan posisi relatif antar-perangkat Ultra-Wideband di sekitar"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Mengizinkan aplikasi menentukan posisi relatif antar-perangkat Ultra-Wideband di sekitar"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informasi Layanan Pembayaran NFC Pilihan"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Mengizinkan aplikasi untuk mendapatkan informasi layanan pembayaran NFC pilihan seperti bantuan terdaftar dan tujuan rute."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrol NFC"</string>
@@ -1624,7 +1626,7 @@
<string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Transmisi layar ke perangkat"</string>
<string name="media_route_chooser_searching" msgid="6119673534251329535">"Menelusuri perangkat…"</string>
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Setelan"</string>
- <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Putuskan sambungan"</string>
+ <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Putuskan koneksi"</string>
<string name="media_route_status_scanning" msgid="8045156315309594482">"Memindai..."</string>
<string name="media_route_status_connecting" msgid="5845597961412010540">"Menyambung..."</string>
<string name="media_route_status_available" msgid="1477537663492007608">"Tersedia"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Sekarang Anda dapat memperbesar sebagian layar"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktifkan di Setelan"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Tutup"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"Untuk melanjutkan, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; memerlukan akses ke kamera perangkat."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aktifkan"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privasi Sensor"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikon aplikasi"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Brand image aplikasi"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 3f2b0d5ea2ae..3fa5bbfdc6c5 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"fá aðgang að hreyfingu þinni"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Myndavél"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"taka myndir og taka upp myndskeið"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Nálæg Bluetooth-tæki"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"finna og tengjast nálægum Bluetooth-tækjum"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Nálæg tæki"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"finna og tengjast nálægum tækjum"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Símtalaskrár"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"lesa og skrifa símtalaskrá síma"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Sími"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Leyfir forritinu að finna nálæg Bluetooth-tæki og parast við þau"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"tengjast pöruðum Bluetooth-tækjum"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Leyfir forritinu að tengjast pöruðum Bluetooth-tækjum"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"birta nálægum Bluetooth-tækjum auglýsingar"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Leyfir forritinu að birta nálægum Bluetooth-tækjum auglýsingar"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"ákvarða fjarlægð milli nálægra tækja með ofurbreiðband"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Leyfa forritinu að ákvarða fjarlægð milli nálægra tækja með ofurbreiðband"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Upplýsingar um valda NFC-greiðsluþjónustu"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Gerir forritinu kleift að fá valda NFC-greiðsluþjónustu, svo sem skráða aðstoð og áfangastað leiðar."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"stjórna nándarsamskiptum (NFC)"</string>
@@ -1854,7 +1854,7 @@
<string name="confirm_battery_saver" msgid="5247976246208245754">"Í lagi"</string>
<string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"Til að auka rafhlöðuendingu gerir rafhlöðusparnaður eftirfarandi:\n\n•·Kveikir á dökku þema\n•·Slekkur á eða takmarkar bakgrunnsvirkni, tilteknar myndbrellur og aðra eiginleika eins og „Ok Google“\n\n"<annotation id="url">"Frekari upplýsingar"</annotation></string>
<string name="battery_saver_description" msgid="6794188153647295212">"Til að auka rafhlöðuendingu gerir rafhlöðusparnaður eftirfarandi:\n\n• Kveikir á dökku þema\n• Slekkur á eða takmarkar bakgrunnsvirkni, tilteknar myndbrellur og aðra eiginleika eins og „Ok Google“"</string>
- <string name="data_saver_description" msgid="4995164271550590517">"Gagnasparnaður getur hjálpað til við að draga úr gagnanotkun með því að hindra forrit í að senda eða sækja gögn í bakgrunni. Forrit sem er í notkun getur náð í gögn, en gerir það kannski sjaldnar. Niðurstaðan getur verið, svo dæmi sé tekið, að myndir eru ekki birtar fyrr en þú ýtir á þær."</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"Gagnasparnaður getur hjálpað til við að draga úr gagnanotkun með því að hindra forrit í að senda eða sækja gögn í bakgrunni. Forrit sem er í notkun getur náð í gögn, en gerir það kannski sjaldnar. Niðurstaðan getur verið að myndir eru ekki birtar fyrr en þú ýtir á þær, svo dæmi sé tekið."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Kveikja á gagnasparnaði?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Kveikja"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Nú geturðu stækkað hluta skjásins"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Kveikja á í stillingum"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Hunsa"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Kveikja"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Opna á hljóðnema tækisins"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Opna fyrir myndavél tækisins"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Fyrir &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; og öll forrit og þjónustur"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Opna á"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Persónuvernd skynjara"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Forritstákn"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Mynd af merki forrits"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 3f159da1c0b4..451598a0af7c 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"Consente di accedere all\'attività fisica"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Fotocamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"scattare foto e registrare video"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Dispositivi Bluetooth nelle vicinanze"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"Rilevamento e connessione a dispositivi Bluetooth nelle vicinanze"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Dispositivi nelle vicinanze"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"Consente di rilevare dispositivi nelle vicinanze e di connettersi a tali dispositivi"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Registri chiamate"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"leggere e modificare il registro chiamate del telefono"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefono"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Consente all\'app di rilevare e accoppiare dispositivi Bluetooth nelle vicinanze"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"Connessione a dispositivi Bluetooth accoppiati"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Consente all\'app di connettersi ai dispositivi Bluetooth accoppiati"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"Pubblicità su dispositivi Bluetooth vicini"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Consente all\'app di fare pubblicità sui dispositivi Bluetooth nelle vicinanze"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"Possibilità di stabilire la posizione relativa tra dispositivi a banda ultralarga nelle vicinanze"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Consenti all\'app di stabilire la posizione relativa tra dispositivi a banda ultralarga nelle vicinanze"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informazioni del servizio di pagamento NFC preferito"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Consente all\'app di recuperare informazioni del servizio di pagamento NFC preferito, quali destinazione della route e identificatori applicazione registrati."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controllo Near Field Communication"</string>
@@ -1901,7 +1901,7 @@
<string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Notte di un giorno feriale"</string>
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fine settimana"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string>
- <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sonno"</string>
+ <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Notte"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> sta disattivando alcuni suoni"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Si è verificato un problema interno con il dispositivo, che potrebbe essere instabile fino al ripristino dei dati di fabbrica."</string>
<string name="system_error_manufacturer" msgid="703545241070116315">"Si è verificato un problema interno con il dispositivo. Per informazioni dettagliate, contatta il produttore."</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Ora puoi ingrandire parte dello schermo"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Attiva nelle Impostazioni"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Ignora"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Attiva"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Sblocca il microfono del dispositivo"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Sblocca la fotocamera del dispositivo"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Per &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;, nonché per tutti i servizi e le app"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Sblocca"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacy relativa ai sensori"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icona dell\'applicazione"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Immagine del branding dell\'applicazione"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index c270c4df7693..fdb3b167644d 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -325,8 +325,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"גישה לפעילות הגופנית שלך"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"מצלמה"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"צילום תמונות והקלטת וידאו"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"‏מכשירי Bluetooth בקרבת מקום"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"‏גילוי מכשירי Bluetooth בקרבת מקום והתחברות אליהם"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"מכשירים קרובים"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"איתור מכשירים שנמצאים בקרבת מקום והתחברות אליהם"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"יומני שיחות"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"קריאה וכתיבה של יומן השיחות של הטלפון"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"טלפון"</string>
@@ -544,10 +544,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"‏מאפשרת לאפליקציה לגלות מכשירי Bluetooth בקרבת מקום ולבצע התאמה איתם"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"‏התחברות למכשירי Bluetooth מתאימים"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"‏מאפשרת לאפליקציה להתחבר למכשירי Bluetooth מותאמים"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"‏פרסום במכשירי Bluetooth בקרבת מקום"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"‏האפליקציה תוכל לפרסם במכשירי Bluetooth בקרבת מקום"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"זיהוי מיקום יחסי בין מכשירי \'תחום רחב סרט\' קרובים"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"האפליקציה תזהה את המיקום היחסי בין מכשירים קרובים שמשדרים בטכנולוגיה \'תחום רחב סרט\'"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏פרטים על שירות תשלום מועדף ב-NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏מאפשרת לאפליקציה לקבל פרטים על שירות תשלום מועדף ב-NFC, כמו עזרים רשומים ויעד של נתיב."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"שליטה בתקשורת מטווח קצר"</string>
@@ -2327,9 +2327,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"עכשיו אפשר להגדיל חלק מהמסך"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"הפעלה בהגדרות"</string>
<string name="dismiss_action" msgid="1728820550388704784">"סגירה"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"‏כדי להמשיך, האפליקציה &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; צריכה גישה למיקרופון של המכשיר שלך."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"‏כדי להמשיך, האפליקציה &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; צריכה גישה למצלמה של המכשיר שלך."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"הפעלה"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"ביטול חסימת המיקרופון של המכשיר"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"ביטול החסימה של מצלמת המכשיר"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"‏עבור &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ולכל האפליקציות והשירותים"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"ביטול חסימה"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"פרטיות חיישנים"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"סמל האפליקציה"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"תדמית המותג של האפליקציה"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 50a3b1b44f1a..37ad3c47a6a4 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"身体活動にアクセス"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"カメラ"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"写真と動画の撮影"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"付近の Bluetooth デバイス"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"付近の Bluetooth デバイスの検出と接続"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"付近のデバイス"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"付近のデバイスの検出と接続"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"通話履歴"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"通話履歴の読み取りと書き込み"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"電話"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"付近の Bluetooth デバイスの検出とペア設定をアプリに許可します"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ペア設定された Bluetooth デバイスへの接続"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ペア設定された Bluetooth デバイスへの接続をアプリに許可します"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"付近の Ultra Wideband デバイス間の相対位置の特定"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"付近の Ultra Wideband デバイス間の相対位置の特定をアプリに許可します"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"優先される NFC お支払いサービスの情報"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"登録されている支援やルートの目的地など、優先される NFC お支払いサービスの情報を取得することをアプリに許可します。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFCの管理"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"画面の一部を拡大できるようになりました"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"[設定] で ON にする"</string>
<string name="dismiss_action" msgid="1728820550388704784">"閉じる"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"続行するには、&lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; にデバイスのマイクへのアクセスを許可する必要があります。"</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"続行するには、&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; にデバイスのカメラへのアクセスを許可する必要があります。"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ON にする"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"センサー プライバシー"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"アプリのアイコン"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"アプリのブランド イメージ"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index d977f7fc690b..1f1b6deb498b 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ფიზიკური აქტივობაზე წვდომა"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"კამერა"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ფოტოებისა და ვიდეოების გადაღება"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"ახლომახლო Bluetooth მოწყობილობები"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"ახლომახლო Bluetooth მოწყობილობების აღმოჩენა და მათთან დაკავშირება"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"ახლომახლო მოწყობილობები"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"ახლომახლო მოწყობილობების აღმოჩენა და დაკავშირება"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"ზარების ჟურნალები"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ზარების ჟურნალის წაკითხვა და მასში ჩაწერა"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ტელეფონი"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"საშუალებას აძლევს აპს, აღმოაჩინოს ახლომახლო Bluetooth მოწყობილობები დასაწყვილებლად"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"დაწყვილებულ Bluetooth მოწყობილობებთან დაკავშირება"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"საშუალებას აძლევს აპს, დაუკავშირდეს დაწყვილებულ Bluetooth მოწყობილობებს"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"შედარებითი პოზიციის დადგენა ახლომახლო ულტრაფართო სიხშირის მოწყობილობების შესახებ"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ნებას რთავს აპს, დაადგინოს შედარებითი პოზიცია ახლომახლო ულტრაფართო სიხშირის მოწყობილობების შესახებ"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"უპირატესი NFC გადახდის სერვისის ინფორმაცია"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"საშუალებას აძლევს აპს, მიიღოს უპირატესი NFC გადახდის სერვისის ინფორმაცია, მაგალითად, რეგისტრირებული დახმარება და დანიშნულება."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ახლო მოქმედების რადიოკავშირი (NFC) მართვა"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"ახლა უკვე შეგიძლიათ ეკრანის ნაწილის გადიდება"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ჩართვა პარამეტრებში"</string>
<string name="dismiss_action" msgid="1728820550388704784">"უარყოფა"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"გასაგრძელებლად &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;-ს თქვენი მოწყობილობის მიკროფონზე წვდომა სჭირდება."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"გასაგრძელებლად &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;-ს თქვენი მოწყობილობის კამერაზე წვდომა სჭირდება."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ჩართვა"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"სენსორის კონფიდენციალურობა"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"აპლიკაციის ხატულა"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"აპლიკაციის ბრენდის სურათი"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 0da10d21a9a2..b6951f376083 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"іс-қимыл дерегін алу"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Камера"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"суретке түсіріп, бейне жазу"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Маңайдағы Bluetooth құрылғылары"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"маңайдағы Bluetooth құрылғыларын анықтау және жұптау"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Маңайдағы құрылғылар"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"маңайдағы құрылғыларды анықтау және жалғау"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Қоңырау журналдары"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"телефонның қоңыраулар журналын оқу және жазу"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Телефон"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Қолданбаға маңайдағы Bluetooth құрылғыларын анықтап, жұптауға рұқсат береді."</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"жұпталған Bluetooth құрылғыларына қосылу"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Қолданбаға жұпталған Bluetooth құрылғыларына қосылуға рұқсат береді."</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"маңайдағы кеңжолақты құрылғылардың бір-біріне қатысты орнын анықтау"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Қолданбаға маңайдағы кеңжолақты құрылғылардың бір-біріне қатысты орнын анықтауға мүмкіндік береді."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Таңдаулы NFC төлеу қызметі туралы ақпарат"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Қолданба тіркелген көмектер және баратын жер маршруты сияқты таңдаулы NFC төлеу қызметі туралы ақпаратты ала алатын болады."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC функциясын басқару"</string>
@@ -1290,7 +1292,7 @@
<string name="volume_icon_description_notification" msgid="579091344110747279">"Хабар дыбысының қаттылығы"</string>
<string name="ringtone_default" msgid="9118299121288174597">"Әдепкі рингтон"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"Әдепкі (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
- <string name="ringtone_silent" msgid="397111123930141876">"Ешқандай"</string>
+ <string name="ringtone_silent" msgid="397111123930141876">"Жоқ"</string>
<string name="ringtone_picker_title" msgid="667342618626068253">"Қоңырау әуендері"</string>
<string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Дабыл сигналдары"</string>
<string name="ringtone_picker_title_notification" msgid="6387191794719608122">"Хабарландыру сигналдары"</string>
@@ -1854,7 +1856,7 @@
<string name="confirm_battery_saver" msgid="5247976246208245754">"Жарайды"</string>
<string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"Батарея жұмысының ұзақтығын арттыру үшін Батареяны үнемдеу режимі:\n\n•қараңғы тақырыпты іске қосады;\n•фондық әрекеттерді, кейбір көрнекі әсерлерді және \"Ok Google\" сияқты басқа да функцияларды өшіреді не шектейді.\n\n"<annotation id="url">"Толығырақ"</annotation></string>
<string name="battery_saver_description" msgid="6794188153647295212">"Батарея ұзағырақ жұмыс істеуі үшін, Батареяны үнемдеу режимі:\n\n• қараңғы тақырыпты қосады;\n•фондық жұмысты, кейбір визуалды әсерлерді және \"Ok Google\" сияқты басқа функцияларды өшіреді не шектейді."</string>
- <string name="data_saver_description" msgid="4995164271550590517">"Дерек шығынын азайту үшін Трафикті үнемдеу функциясы кейбір қолданбаларға деректерді фондық режимде жіберуге және алуға жол бермейді. Ашық тұрған қолданба деректерді пайдаланады, бірақ шектеулі шамада (мысалы, кескіндер оларды түрткенге дейін көрсетілмейді)."</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"Дерек шығынын азайту үшін Трафикті үнемдеу режимінде кейбір қолданбаларға деректі фондық режимде жіберуге және алуға тыйым салынады. Ашық тұрған қолданба деректі шектеулі шамада пайдаланады (мысалы, кескіндер оларды түрткенге дейін көрсетілмейді)."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Трафикті үнемдеу функциясын қосу керек пе?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Қосу"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Енді экранның бір бөлігін ұлғайтуға болады."</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Параметрлер бөлімінен қосу"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Қабылдамау"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Жалғастыру үшін &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; қолданбасы құрылғыңыздың микрофонына рұқсат алу керек."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Жалғастыру үшін &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; қолданбасы құрылғыңыздың камерасына рұқсат алу керек."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Қосу"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Датчикке қатысты құпиялылық"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Қолданба белгішесі"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Қолданба брендін ілгері жылжыту кескіні"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 5740b991a071..170e1606cca6 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ចូលប្រើ​សកម្មភាព​រាងកាយ​របស់អ្នក"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"កាមេរ៉ា"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ថតរូប និងថតវីដេអូ"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"ឧបករណ៍​ប៊្លូធូសដែលនៅជិត"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"ស្វែងរក និងភ្ជាប់ទៅឧបករណ៍​ប៊្លូធូស​ដែលនៅជិត"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"ឧបករណ៍​ដែលនៅជិត"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"ស្វែងរក និងភ្ជាប់ទៅ​ឧបករណ៍​ដែលនៅជិត"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"កំណត់​ហេតុ​ហៅ​ទូរសព្ទ"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"អាន និងសរសេរ​កំណត់​ហេតុ​ហៅ​ទូរសព្ទ"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ទូរសព្ទ"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"អនុញ្ញាតឱ្យកម្មវិធី​ស្វែងរក និងផ្គូផ្គង​ឧបករណ៍​ប៊្លូធូសដែលនៅជិត"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ភ្ជាប់ទៅឧបករណ៍​ប៊្លូធូសដែលបានផ្គូផ្គង"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"អនុញ្ញាតឱ្យ​កម្មវិធីភ្ជាប់ទៅ​ឧបករណ៍​ប៊្លូធូសដែលបានផ្គូផ្គង"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"កំណត់ចម្ងាយពាក់ព័ន្ធរវាងឧបករណ៍ Ultra-Wideband ដែលនៅជិត"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"អនុញ្ញាតឱ្យ​កម្មវិធី​កំណត់ចម្ងាយ​ពាក់ព័ន្ធ​រវាងឧបករណ៍ Ultra-Wideband ដែលនៅជិត"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ព័ត៌មានអំពី​សេវាបង់ប្រាក់តាម NFC ជាអាទិភាព"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"អនុញ្ញាតឱ្យ​កម្មវិធី​ទទួលបាន​ព័ត៌មានអំពី​សេវាបង់ប្រាក់តាម nfc ជាអាទិភាព​ដូចជា គោលដៅផ្លូវ និង​ព័ត៌មាន​កំណត់អត្តសញ្ញាណ​កម្មវិធី ដែលបានចុះឈ្មោះ​ជាដើម។"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ពិនិត្យ​ការ​ទាក់ទង​នៅ​ក្បែរ (NFC)"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"ឥឡូវនេះ អ្នកអាចពង្រីក​ផ្នែកនៃអេក្រង់​របស់អ្នកបានហើយ"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"បើកនៅក្នុងការកំណត់"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ច្រានចោល"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ដើម្បីបន្ត &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ត្រូវការសិទ្ធិចូលប្រើ​មីក្រូហ្វូន​របស់ឧបករណ៍អ្នក។"</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"ដើម្បីបន្ត &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ត្រូវការសិទ្ធិ​ចូលប្រើ​កាមេរ៉ា​របស់ឧបករណ៍អ្នក។"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"បើក"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ឯកជនភាព​ឧបករណ៍​ចាប់សញ្ញា"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"រូប​កម្មវិធី"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"រូបភាព​ផ្សព្វផ្សាយម៉ាក​កម្មវិធី"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 222f7710eccc..48a9169fb22a 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -319,8 +319,10 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ನಿಮ್ಮ ದೈಹಿಕ ಚಟುವಟಿಕೆಯನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"ಕ್ಯಾಮರಾ"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ಚಿತ್ರಗಳನ್ನು ತೆಗೆಯಲು, ವೀಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಲು"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"ಸಮೀಪದಲ್ಲಿರುವ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳು"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"ಸಮೀಪದಲ್ಲಿರುವ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ಅನ್ವೇಷಿಸಿ ಮತ್ತು ಅವುಗಳಿಗೆ ಕನೆಕ್ಟ್ ಮಾಡಿ"</string>
+ <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
+ <skip />
<string name="permgrouplab_calllog" msgid="7926834372073550288">"ಕರೆಯ ಲಾಗ್‌"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ಪೋನ್‌ ಕರೆಯ ಲಾಗ್‌ ಅನ್ನು ಓದಿ ಮತ್ತು ಬರೆಯಿರಿ"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ಫೋನ್"</string>
@@ -538,6 +540,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ಸಮೀಪದಲ್ಲಿರುವ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ಅನ್ವೇಷಿಸಲು ಮತ್ತು ಅವುಗಳಿಗೆ ಜೋಡಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸಿ"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ಜೋಡಿಸಿರುವ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳಿಗೆ ಕನೆಕ್ಟ್ ಮಾಡಿ"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ಜೋಡಿಸಲಾಗಿರುವ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳಿಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
+ <skip />
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
+ <skip />
<!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
<skip />
<!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
@@ -2259,9 +2265,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"ನೀವು ಇದೀಗ ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನ ಭಾಗವನ್ನು ಹಿಗ್ಗಿಸಬಹುದು"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಆನ್ ಮಾಡಿ"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ವಜಾಗೊಳಿಸಿ"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ಮುಂದುವರಿಯಲು, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ಗೆ ನಿಮ್ಮ ಸಾಧನದ ಮೈಕ್ರೋಫೋನ್‌ನ ಪ್ರವೇಶದ ಅಗತ್ಯವಿದೆ."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"ಮುಂದುವರಿಯಲು, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ಗೆ ನಿಮ್ಮ ಸಾಧನದ ಕ್ಯಾಮರಾದ ಪ್ರವೇಶದ ಅಗತ್ಯವಿದೆ."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ಆನ್ ಮಾಡಿ"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ಸೆನ್ಸರ್ ಗೌಪ್ಯತೆ"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ಅಪ್ಲಿಕೇಶನ್‌ ಐಕಾನ್‌"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ಅಪ್ಲಿಕೇಶನ್ ಬ್ರ್ಯಾಂಡಿಂಗ್ ಚಿತ್ರ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index c4d8a7b43a86..c72222caee9c 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"신체 활동 정보에 액세스"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"카메라"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"사진 및 동영상 촬영"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"근처의 블루투스 기기"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"근처의 블루투스 기기를 찾고 연결"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"근처 기기"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"근처 기기 검색 및 연결"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"통화 기록"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"통화 기록 읽고 쓰기"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"전화"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"앱이 근처의 블루투스 기기를 찾고 페어링하도록 허용"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"페어링된 블루투스 기기에 연결"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"앱이 페어링된 블루투스 기기에 연결하도록 허용"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"근처 초광대역 기기 간 상대적 위치 파악"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"앱이 근처의 초광대역 기기 간 상대적 위치를 파악하도록 허용"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"기본 NFC 결제 서비스 정보"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"앱이 등록된 AID와 경로 목적지 같은 기본 NFC 결제 서비스 정보를 확인하도록 허용합니다."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC(Near Field Communication) 제어"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"이제 화면 일부를 확대할 수 있습니다."</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"설정에서 사용 설정"</string>
<string name="dismiss_action" msgid="1728820550388704784">"닫기"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"계속하려면 &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;에서 기기 마이크에 액세스해야 합니다."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"계속하려면 &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;에서 기기 카메라에 액세스해야 합니다."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"사용"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"센서 개인정보 보호"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"애플리케이션 아이콘"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"애플리케이션 브랜드 이미지"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 67889de203b6..b27e1eaec641 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"кыймыл-аракеттериңизге көз салып турганга мүмкүнчүлүк алат"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Камера"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"сүрөт жана видео тартууга"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Жакын жердеги Bluetooth түзмөктөрү"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"жакын жердеги Bluetooth түзмөктөрүн аныктоо жана туташуу"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Жакын жердеги түзмөктөр"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"жакын жердеги түзмөктөрдү аныктоо жана туташуу"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Чалуулар тизмеси"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"телефондогу чалуулар тизмесин окуу жана жазуу"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Телефон"</string>
@@ -391,8 +391,8 @@
<string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"Бул колдонмо башка колдонмолордун же экрандын башка бөлүгүнүн үстүндө көрүнүшү мүмкүн. Ал колдонмолорду пайдаланууга же алардын көрсөтүлүшүнө тоскоолдук жаратышы мүмкүн."</string>
<string name="permlab_runInBackground" msgid="541863968571682785">"фондо иштей берсин"</string>
<string name="permdesc_runInBackground" msgid="4344539472115495141">"Бул колдонмо фондо иштей берет. Батареяңыз тез эле отуруп калышы мүмкүн."</string>
- <string name="permlab_useDataInBackground" msgid="783415807623038947">"фондо дайын-даректерди өткөрө берсин"</string>
- <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Бул колдонмо фондо дайын-даректерди өткөрө берет. Дайындарды көбүрөөк өткөрүшү мүмкүн."</string>
+ <string name="permlab_useDataInBackground" msgid="783415807623038947">"фондо маалыматтарды өткөрө берсин"</string>
+ <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Бул колдонмо фондо маалыматтарды өткөрө берет. Дайындарды көбүрөөк өткөрүшү мүмкүн."</string>
<string name="permlab_persistentActivity" msgid="464970041740567970">"колдонмону үзгүлтүксүз иштетүү"</string>
<string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"Колдонмого өзүнүн бөлүктөрүн эстутумда туруктуу кармоого уруксат берет.Бул эстутумдун башка колдонмолорго жетиштүүлүгүн чектеши жана телефондун иштешин жайлатышы мүмкүн."</string>
<string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"Колдонмого өз бөлүктөрүн эстутумда туруктуу сактоого уруксат берет. Бул башка колдонмолор үчүн жеткиликтүү болгон эстутумду чектеп, Android TV түзмөгүңүздүн иштешин жайлатышы мүмкүн."</string>
@@ -423,14 +423,14 @@
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Бул колдонмо чалууларыңыздын таржымалын окуй алат."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"чалуулар тизмегин жаздыруу"</string>
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Колдонмого планшетиңиздин чалуулар тизмегин, анын ичинде, чыгыш жана кириш чалууларына тиешелүү берилиштерди өзгөртүү уруксатын берет. Зыяндуу колдонмолор муну колдонуп чалуулар тизмегин өзгөртө же жок кыла алышат."</string>
- <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Колдонмого Android TV түзмөгүңүздүн чалуулар тизмесин, анын ичинде кирүүчү жана чыгуучу чалуулар тууралуу дайын-даректерди өзгөртүүгө уруксат берет. Зыянкеч колдонмолор ал уруксатты колдонуп чалуулар тизмеңизди тазалап же өзгөртүп коюшу мүмкүн."</string>
+ <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Колдонмого Android TV түзмөгүңүздүн чалуулар тизмесин, анын ичинде кирүүчү жана чыгуучу чалуулар тууралуу маалыматтарды өзгөртүүгө уруксат берет. Зыянкеч колдонмолор ал уруксатты колдонуп чалуулар тизмеңизди тазалап же өзгөртүп коюшу мүмкүн."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Колдонмого телефонуңуздун чалуулар тизмегин, анын ичинде, чыгыш жана кириш чалууларына тиешелүү берилиштерди өзгөртүү уруксатын берет. Зыяндуу колдонмолор муну колдонуп чалуулар тизмегин өзгөртө же жок кыла алышат."</string>
<string name="permlab_bodySensors" msgid="3411035315357380862">"дене-бой сенсорлоруна (жүрөктүн кагышын өлчөгүчтөр сыяктуу) уруксат"</string>
- <string name="permdesc_bodySensors" product="default" msgid="2365357960407973997">"Колдонмого жүрөгүңүздүн согушу сыяктуу дене-бой абалыңызды көзөмөлдөгөн сенсорлордогу дайын-даректерди көрүп туруу мүмкүнчүлүгүн берет."</string>
+ <string name="permdesc_bodySensors" product="default" msgid="2365357960407973997">"Колдонмого жүрөгүңүздүн согушу сыяктуу дене-бой абалыңызды көзөмөлдөгөн сенсорлордогу маалыматтарды көрүп туруу мүмкүнчүлүгүн берет."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Жылнаамадагы иш-чараларды жана алардын чоо-жайын окуу"</string>
- <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Бул колдонмо планшетиңизде сакталган жылнаамадагы иш-чаралардын баарын окуп жана андагы дайын-даректерди бөлүшүп же сактай алат."</string>
+ <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Бул колдонмо планшетиңизде сакталган жылнаамадагы иш-чаралардын баарын окуп жана андагы маалыматтарды бөлүшүп же сактай алат."</string>
<string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Бул колдонмо Android TV түзмөгүңүздө сакталган жылнаама иш-чараларынын баарын окуп, ошондой эле жылнаама дайындарын бөлүшүп же сактай алат."</string>
- <string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"Бул колдонмо телефонуңузда сакталган жылнаамадагы иш-чаралардын баарын окуп жана андагы дайын-даректерди бөлүшүп же сактай алат."</string>
+ <string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"Бул колдонмо телефонуңузда сакталган жылнаамадагы иш-чаралардын баарын окуп жана андагы маалыматтарды бөлүшүп же сактай алат."</string>
<string name="permlab_writeCalendar" msgid="6422137308329578076">"ээсинен уруксат албай, күнбаракка иш-аракеттерди кошуу же өзгөртүү жана конокторго чакыруу жөнөтүү"</string>
<string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"Бул колдонмо планшетиңизге жылнаама иш-чараларын кошуп, алып салып же өзгөртүшү мүмкүн. Бул колдонмо жылнаама ээсинин атынан билдирүүлөрдү жөнөтүп же ээсине эскертпестен иш-чараларды өзгөртүшү мүмкүн."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"Бул колдонмо Android TV түзмөгүңүзгө жылнаама иш-чараларын кошуп, ошондой эле аларды өчүрүшү же өзгөртүшү мүмкүн. Бул колдонмо жылнаама ээсинин атынан билдирүүлөрдү жөнөтүп же ээсине эскертпестен иш-чараларды өзгөртүшү мүмкүн."</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Колдонмого жакын жердеги Bluetooth түзмөктөрүн аныктап, жупташтырууга уруксат берет"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"жупташтырылган Bluetooth түзмөктөрү"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Колдонмого жупташтырылган Bluetooth түзмөктөрү менен байланышууга уруксат берет"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"кең тилкелүү тармак аркылуу туташа турган жакын жердеги түзмөктөрдү аныктоо"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Колдонмо кең тилкелүү тармак аркылуу туташа турган жакын жердеги түзмөктөрдү аныктай алат"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Тандалган NFC төлөм кызматы жөнүндө маалымат"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Колдонмого катталган жардам же көздөлгөн жерге маршрут сыяктуу тандалган nfc төлөм кызматы жөнүндө маалыматты алууга уруксат берүү."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication көзөмөлү"</string>
@@ -724,9 +726,9 @@
<string name="policylab_limitPassword" msgid="4851829918814422199">"Сырсөз эрежелерин коюу"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Экран кулпусунун сырсөздөрү менен PIN\'дерине уруксат берилген узундук менен белгилерди көзөмөлдөө."</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"Экран кулпусун ачуу аракеттерин көзөмөлдөө"</string>
- <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Экрандын кулпусу ачылып жатканда туура эмес терилген сырсөздөрдүн санын текшерип, эгер алардын саны өтө эле көп болсо, планшетти кулпулаңыз же планшеттеги бардык дайын-даректерди тазалап салыңыз."</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Экрандын кулпусу ачылып жатканда туура эмес терилген сырсөздөрдүн санын текшерип, эгер алардын саны өтө эле көп болсо, планшетти кулпулаңыз же планшеттеги бардык маалыматтарды тазалап салыңыз."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Экрандын кулпусун ачуу учурунда сырсөздөр канча жолу туура эмес терилгенин тескөө жана сырсөз өтө көп жолу туура эмес терилген болсо, Android TV түзмөгүңүздү кулпулап же Android TV түзмөгүңүздөгү бардык дайын-даректериңизди тазалап салуу."</string>
- <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Экрандын кулпусу ачылып жатканда туура эмес терилген сырсөздөрдүн санын текшерип, эгер алардын саны өтө эле көп болсо, телефонду кулпулаңыз же телефондогу бардык дайын-даректерди тазалап салыңыз."</string>
+ <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Экрандын кулпусу ачылып жатканда туура эмес терилген сырсөздөрдүн санын текшерип, эгер алардын саны өтө эле көп болсо, телефонду кулпулаңыз же телефондогу бардык маалыматтарды тазалап салыңыз."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Экрандын кулпусун ачуу учурунда туура эмес терилген сырсөздөрдү тескөө жана сырсөз өтө көп жолу туура эмес терилген болсо, планшетти кулпулап же бул колдонуучунун бардык дайындарын тазалап салуу."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Экрандын кулпусун ачуу учурунда сырсөздөр канча жолу туура эмес терилгенин тескөө жана сырсөз өтө көп жолу туура эмес терилген болсо, Android TV түзмөгүңүздү кулпулап же колдонуучунун бардык дайындарын тазалап салуу."</string>
<string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Экрандын кулпусун ачуу учурунда туура эмес терилген сырсөздөрдү тескөө жана сырсөз өтө көп жолу туура эмес терилген болсо, телефонду кулпулап же бул колдонуучунун бардык дайындарын тазалап салуу."</string>
@@ -735,9 +737,9 @@
<string name="policylab_forceLock" msgid="7360335502968476434">"Экранды кулпулоо"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"Экран качан жана кантип кулпулана турганын чечет."</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"Бардык маалыматты өчүрүү"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Алдын-ала эскертпестен, баштапкы абалга келтирүү функциясы менен планшеттеги бардык дайын-даректерди өчүрөт."</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Алдын-ала эскертпестен, баштапкы абалга келтирүү функциясы менен планшеттеги бардык маалыматтарды өчүрөт."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Android TV түзмөгүңүздүн дайындарын эскертүүсүз кайра башынан жөндөө аркылуу тазалоо."</string>
- <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Алдын-ала эскертпестен, баштапкы абалга келтирүү функциясы менен телефондогу бардык дайын-даректерди өчүрөт."</string>
+ <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Алдын-ала эскертпестен, баштапкы абалга келтирүү функциясы менен телефондогу бардык маалыматтарды өчүрөт."</string>
<string name="policylab_wipeData_secondaryUser" msgid="413813645323433166">"Колдонуучунун дайындарын тазалоо"</string>
<string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Бул колдонуучунун ушул планшеттеги дайындарын эскертүүсүз тазалоо."</string>
<string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"Бул Android TV түзмөгүндөгү бул колдонуучу дайындарын эскертүүсүз тазалоо."</string>
@@ -1691,7 +1693,7 @@
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"КҮЙҮК"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ӨЧҮК"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> кызматына түзмөгүңүздү толугу менен көзөмөлдөөгө уруксат бересизби?"</string>
- <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Эгер <xliff:g id="SERVICE">%1$s</xliff:g> күйгүзүлсө, түзмөгүңүз дайын-даректерди шифрлөөнү күчтөндүрүү үчүн экраныңыздын кулпусун пайдаланбайт."</string>
+ <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Эгер <xliff:g id="SERVICE">%1$s</xliff:g> күйгүзүлсө, түзмөгүңүз маалыматтарды шифрлөөнү күчтөндүрүү үчүн экраныңыздын кулпусун пайдаланбайт."</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"Толук көзөмөл атайын мүмкүнчүлүктөрдү пайдаланууга керек, бирок калган көпчүлүк колдонмолорго кереги жок."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Экранды көрүп, көзөмөлдөө"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Кызмат экрандагы нерселерди окуп, материалды башка колдонмолордун үстүнөн көрсөтөт."</string>
@@ -1854,7 +1856,7 @@
<string name="confirm_battery_saver" msgid="5247976246208245754">"ЖАРАЙТ"</string>
<string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"Батареяны көбүрөөк убакытка жеткирүү үчүн Батареяны үнөмдөгүч режиминде:\n\n• Караңгы тема күйгүзүлөт\n• Фондогу аракеттерди, айрым визуалдык эффекттерди жана \"Окей Google\" сыяктуу башка функцияларды өчүрөт же чектейт\n\n"<annotation id="url">"Кеңири маалымат"</annotation></string>
<string name="battery_saver_description" msgid="6794188153647295212">"Батареяны көбүрөөк убакытка жеткирүү үчүн Батареяны үнөмдөгүч режими:\n\n• Караңгы тема күйгүзүлөт\n• Фондогу аракеттерди, айрым визуалдык эффекттерди жана \"Окей Google\" сыяктуу башка функцияларды өчүрөт же чектейт"</string>
- <string name="data_saver_description" msgid="4995164271550590517">"Трафикти үнөмдөө режиминде айрым колдонмолор дайын-даректерди фондо өткөрө алышпайт. Учурда сиз пайдаланып жаткан колдонмо дайын-даректерди жөнөтүп/ала алат, бирок адаттагыдан азыраак өткөргөндүктөн, анын айрым функциялары талаптагыдай иштебей коюшу мүмкүн. Мисалы, сүрөттөр басылмайынча жүктөлбөйт."</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"Трафикти үнөмдөө режиминде айрым колдонмолор маалыматтарды фондо өткөрө алышпайт. Учурда сиз пайдаланып жаткан колдонмо маалыматтарды жөнөтүп/ала алат, бирок адаттагыдан азыраак өткөргөндүктөн, анын айрым функциялары талаптагыдай иштебей коюшу мүмкүн. Мисалы, сүрөттөр басылмайынча жүктөлбөйт."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Трафикти үнөмдөө режимин иштетесизби?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Күйгүзүү"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Эми экрандын бир бөлүгүн чоңойто аласыз"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Жөндөөлөрдөн күйгүзүү"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Жабуу"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Улантуу үчүн &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; колдонмосуна түзмөгүңүздүн микрофонун пайдаланууга уруксат беришиңиз керек."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Улантуу үчүн &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; колдонмосуна түзмөгүңүздүн камерасын пайдаланууга уруксат беришиңиз керек."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Күйгүзүү"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Сенсордун купуялыгы"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Колдонмонун сүрөтчөсү"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Колдонмонун брендинин сүрөтү"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index ae1e36ec06bd..38491837cdb1 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ເຂົ້າເຖິງກິດຈະກຳທາງກາຍະພາບຂອງທ່ານ"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"ກ້ອງ"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ຖ່າຍ​ຮູບ ແລະ​ບັນ​ທຶກວິ​ດີ​ໂອ"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"ອຸປະກອນ Bluetooth ທີ່ຢູ່ໃກ້ຄຽງ"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"ຄົ້ນພົບ ແລະ ເຊື່ອມຕໍ່ຫາອຸປະກອນ Bluetooth ທີ່ຢູ່ໃກ້ຄຽງ"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"ອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງ"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"ຄົ້ນພົບ ແລະ ເຊື່ອມຕໍ່ຫາອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງ"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"ບັນທຶກການໂທ"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ອ່ານ ແລະ ຂຽນບັນທຶກການໂທ"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ໂທລະສັບ"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ອະນຸຍາດໃຫ້ແອັບຄົ້ນພົບ ແລະ ຈັບຄູ່ອຸປະກອນ Bluetooth ທີ່ຢູ່ໃກ້ຄຽງໄດ້"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ເຊື່ອມຕໍ່ຫາອຸປະກອນ Bluetooth ທີ່ຈັບຄູ່ໄວ້"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ອະນຸຍາດໃຫ້ແອັບເຊື່ອມຕໍ່ຫາອຸປະກອນ Bluetooth ທີ່ຈັບຄູ່ແລ້ວໄດ້"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"ໂຄສະນາຫາອຸປະກອນ Bluetooth ທີ່ຢູ່ໃກ້ຄຽງໄດ້"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"ອະນຸຍາດໃຫ້ແອັບໂຄສະນາຫາອຸປະກອນ Bluetooth ທີ່ຢູ່ໃກ້ຄຽງໄດ້"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"ກຳນົດຕຳແໜ່ງທີ່ສຳພັນກັນລະຫວ່າງອຸປະກອນ Ultra-Wideband ທີ່ຢູ່ໃກ້ຄຽງ"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ອະນຸຍາດໃຫ້ແອັບກຳນົດຕຳແໜ່ງທີ່ສຳພັນກັນລະຫວ່າງອຸປະກອນ Ultra-Wideband ທີ່ຢູ່ໃກ້ຄຽງ"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ຂໍ້ມູນບໍລິການການຈ່າຍເງິນ NFC ທີ່ຕ້ອງການ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ອະນຸຍາດໃຫ້ແອັບຮັບຂໍ້ມູນບໍລິການການຈ່າຍເງິນ NFC ທີ່ຕ້ອງການໄດ້ ເຊັ່ນ: ການຊ່ວຍເຫຼືອແບບລົງທະບຽນ ແລະ ປາຍທາງເສັ້ນທາງ."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ຄວບຄຸມ Near Field Communication"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"ຕອນນີ້ທ່ານສາມາດຂະຫຍາຍບາງສ່ວນຂອງໜ້າຈໍໄດ້ແລ້ວ"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ເປີດໃຊ້ໃນການຕັ້ງຄ່າ"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ປິດໄວ້"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ເພື່ອດຳເນີນການຕໍ່, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ຕ້ອງການສິດເຂົ້າເຖິງໄມໂຄຣໂຟນອຸປະກອນທ່ານ."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"ເພື່ອດຳເນີນການຕໍ່, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ຕ້ອງການສິດເຂົ້າເຖິງກ້ອງຖ່າຍຮູບຂອງອຸປະກອນທ່ານ."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ເປີດໃຊ້"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"ຍົກເລີກການບລັອກໄມໂຄຣໂຟນອຸປະກອນ"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"ຍົກເລີກການບລັອກອຸປະກອນກ້ອງຖ່າຍຮູບ"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"ສຳລັບ &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ແລະ ແອັບ ແລະ ບໍລິການທັງໝົດ"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"ຍົກເລີກການບລັອກ"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ຄວາມເປັນສ່ວນຕົວເຊັນເຊີ"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ໄອຄອນແອັບພລິເຄຊັນ"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ຮູບແບຣນແອັບພລິເຄຊັນ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 8744a8b152f4..a4f41de1ec7e 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -325,8 +325,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"galimybė pasiekti fizinę veiklą"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Fotoaparatas"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"fotografuoti ir filmuoti"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"„Bluetooth“ įrenginiai netoliese"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"aptikti „Bluetooth“ įrenginius netoliese ir prisijungti prie jų"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Įrenginiai netoliese"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"aptikti netoliese esančius įrenginius ir prisijungti prie jų"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Skambučių žurnalai"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"skaityti ir rašyti telefono skambučių žurnalą"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefonas"</string>
@@ -544,10 +544,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Leidžiama programai aptikti ir susieti „Bluetooth“ įrenginius netoliese"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"prisijungimas prie susietų „Bluetooth“ įrenginių"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Leidžiama programai prisijungti prie susietų „Bluetooth“ įrenginių"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"nustatyti apyt. netoliese es. itin plataus dažnio juostos įreng. poziciją"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Leisti programai nustatyti apytikslę netoliese esančių itin plataus dažnio juostos įrenginių poziciją"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Pageidaujama ARL mokėjimo paslaugos informacija"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Programai leidžiama gauti pageidaujamą ARL mokamos paslaugos informaciją, pvz., užregistruotą pagalbą ir maršrutų tikslus."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"valdyti artimo lauko perdavimą (angl. „Near Field Communication“)"</string>
@@ -2327,9 +2329,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Dabar galite padidinti dalį ekrano"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Įjungti nustatymuose"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Atmesti"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Įjungti"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Jutiklių privatumas"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Programos piktograma"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Programos prekės ženklo vaizdas"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index b341f326c164..b80e528acfec 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -322,8 +322,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"piekļūt jūsu fiziskajām aktivitātēm"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"uzņemt attēlus un ierakstīt videoklipus"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Tuvumā esošas Bluetooth ierīces"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"atrast tuvumā esošas Bluetooth ierīces un izveidot savienojumu ar tām"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Tuvumā esošās ierīces"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"tuvumā esošu ierīču meklēšana un savienojuma izveide ar tām"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Zvanu žurnāli"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"lasīt un rakstīt tālruņa zvanu žurnālu"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Tālrunis"</string>
@@ -541,10 +541,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Ļauj lietotnei atrast un savienot pārī tuvumā esošas Bluetooth ierīces."</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"piekļūt pārī savienotām Bluetooth ierīcēm"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Ļauj lietotnei piekļūt pārī savienotām Bluetooth ierīcēm."</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"reklamēšana tuvumā esošās Bluetooth ierīcēs"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Atļauj lietotnei veikt reklamēšanu tuvumā esošās Bluetooth ierīcēs"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"novietojuma noteikšana starp tuvu esošām ultraplatjoslas ierīcēm"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Atļaut lietotnei noteikt relatīvo atrašanās vietu starp tuvumā esošām ultraplatjoslas ierīcēm"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informācija par vēlamo NFC maksājumu pakalpojumu"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Ļauj lietotnei iegūt informāciju par vēlamo NFC maksājumu pakalpojumu, piemēram, par reģistrētajiem lietojumprogrammu ID un maršruta galamērķi."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolē tuvlauka saziņu"</string>
@@ -2293,9 +2293,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Tagad varat palielināt ekrāna daļu."</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ieslēgt sadaļā Iestatījumi"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Nerādīt"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Ieslēgt"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Atbloķējiet ierīces mikrofonu"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Atbloķējiet ierīces kameru"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Lietotnei &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; un visām lietotnēm un pakalpojumiem"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Atbloķēt"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensoru konfidencialitāte"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Lietojumprogrammas ikona"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Lietojumprogrammas zīmola attēls"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index d38e9313ca5b..4c32e1448a47 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"пристапете до вашата физичка активност"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Камера"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"фотографира и снима видео"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Уреди со Bluetooth во близина"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"да открива и да се поврзува со уреди со Bluetooth во близина"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Уреди во близина"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"да открива и да се поврзува со уреди во близина"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Евиденција на повици"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"чита и пишува евиденција на повици во телефонот"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Телефон"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Дозволува апликацијата да открива и да се поврзува со спарени уреди со Bluetooth во близина"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"да се поврзува со спарени уреди со Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Дозволува апликацијата да се поврзува со спарени уреди со Bluetooth"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"да рекламира на уреди со Bluetooth во близина"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Дозволува апликацијата да рекламира на уреди со Bluetooth во близина"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"да ја одреди релативната положба помеѓу уредите со ултраширок појас во близина"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Дозволува апликацијата да ја одреди релативната положба помеѓу уредите со ултраширок појас во близина"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информации за претпочитаната услуга за плаќање преку NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дозволува апликацијата да добие информации за претпочитаната услуга за плаќање преку NFC, како регистрирани помагала и дестинација на маршрутата."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"контролирај комуникација на блиско поле"</string>
@@ -1280,7 +1280,7 @@
<string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Поставено ѕвонење на тивко"</string>
<string name="volume_call" msgid="7625321655265747433">"Јачина на звук на дојдовен повик"</string>
<string name="volume_bluetooth_call" msgid="2930204618610115061">"Јачина на звук на дојдовен повик преку Bluetooth"</string>
- <string name="volume_alarm" msgid="4486241060751798448">"Јачина на звук на аларм"</string>
+ <string name="volume_alarm" msgid="4486241060751798448">"Јачина на звук за аларм"</string>
<string name="volume_notification" msgid="6864412249031660057">"Јачина на звук на известување"</string>
<string name="volume_unknown" msgid="4041914008166576293">"Јачина на звук"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Јачина на звук на Bluetooth"</string>
@@ -1492,7 +1492,7 @@
<string name="vpn_text_long" msgid="278540576806169831">"Поврзани сте на <xliff:g id="SESSION">%s</xliff:g>. Допрете за да управувате со мрежата."</string>
<string name="vpn_lockdown_connecting" msgid="6096725311950342607">"Поврзување со секогаш вклучена VPN..."</string>
<string name="vpn_lockdown_connected" msgid="2853127976590658469">"Поврзани со секогаш вклучена VPN"</string>
- <string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"Исклучено од секогаш вклучената VPN"</string>
+ <string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"Не е поврзано со секогаш вклучената VPN"</string>
<string name="vpn_lockdown_error" msgid="4453048646854247947">"Не може да се поврзе на секогаш вклучената VPN"</string>
<string name="vpn_lockdown_config" msgid="8331697329868252169">"Променете ја мрежата или поставките за VPN"</string>
<string name="upload_file" msgid="8651942222301634271">"Избери датотека"</string>
@@ -1624,7 +1624,7 @@
<string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Префрли екран на уред"</string>
<string name="media_route_chooser_searching" msgid="6119673534251329535">"Се бараат уреди..."</string>
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Поставки"</string>
- <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Исклучи"</string>
+ <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Прекини врска"</string>
<string name="media_route_status_scanning" msgid="8045156315309594482">"Скенирање..."</string>
<string name="media_route_status_connecting" msgid="5845597961412010540">"Се поврзува..."</string>
<string name="media_route_status_available" msgid="1477537663492007608">"Достапна"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Сега може да зголемувате дел од екранот"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Вклучи во „Поставки“"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Отфрли"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"За да продолжи, на &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ѝ е потребен пристап до микрофонот на уредот."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"За да продолжи, на &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ѝ е потребен пристап до камерата на уредот."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Вклучи"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Одблокирајте го пристапот до микрофонот на уредот"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Одблокирајте го пристапот до камерата на уредот"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"За &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; и сите апликации и услуги"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Одблокирај"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Приватност на сензорот"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Икона за апликацијата"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Слика за брендирање на апликацијата"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 0c61cf2a9f95..89318ac078c9 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ശാരീരിക പ്രവർത്തനം ആക്‌സസ് ചെയ്യുക"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"ക്യാമറ"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ചിത്രങ്ങളെടുത്ത് വീഡിയോ റെക്കോർഡുചെയ്യുക"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"സമീപമുള്ള Bluetooth ഉപകരണങ്ങൾ"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"സമീപമുള്ള Bluetooth ഉപകരണങ്ങൾ കണ്ടെത്തി കണക്റ്റ് ചെയ്യുക"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"സമീപമുള്ള ഉപകരണങ്ങൾ"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"സമീപമുള്ള ഉപകരണങ്ങൾ കണ്ടെത്തി അവയിലേക്ക് കണക്റ്റ് ചെയ്യുക"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"കോൾ ലോഗ്"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ഫോൺ കോൾ ലോഗ് വായിക്കുകയും എഴുതുകയും ചെയ്യുക"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ഫോണ്‍"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"സമീപമുള്ള Bluetooth ഉപകരണങ്ങൾ കണ്ടെത്താനും ജോടിയാക്കാനും ആപ്പിനെ അനുവദിക്കുന്നു"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ജോടിയായ Bluetooth ഉപകരണങ്ങളിലേക്ക് കണക്റ്റ് ചെയ്യൂ"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ജോടിയാക്കിയ Bluetooth ഉപകരണങ്ങളിലേക്ക് കണക്റ്റ് ചെയ്യാൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"സമീപമുള്ള അൾട്രാ-വെെഡ്ബാൻഡ് ഉപകരണങ്ങൾ തമ്മിലുള്ള ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കൂ"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"സമീപമുള്ള അൾട്രാ-വെെഡ്ബാൻഡ് ഉപകരണങ്ങൾ തമ്മിലുള്ള ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കാൻ ആപ്പിനെ അനുവദിക്കുക"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"തിരഞ്ഞെടുത്ത NFC പേയ്‌മെന്റ് സേവനത്തെ സംബന്ധിച്ച വിവരങ്ങൾ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"റൂട്ട് ലക്ഷ്യസ്ഥാനം, രജിസ്‌റ്റർ ചെയ്തിരിക്കുന്ന സഹായങ്ങൾ എന്നിവ പോലുള്ള, തിരഞ്ഞെടുത്ത NFC പേയ്‌മെന്റ് സേവനത്തെ സംബന്ധിച്ച വിവരങ്ങൾ ലഭിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"സമീപ ഫീൽഡുമായുള്ള ആശയവിനിമയം നിയന്ത്രിക്കുക"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"നിങ്ങളുടെ സ്ക്രീനിന്റെ ഒരു ഭാഗം ഇപ്പോൾ മാഗ്നിഫൈ ചെയ്യാനാകും"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ക്രമീകരണത്തിൽ ഓണാക്കുക"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ഡിസ്‌മിസ് ചെയ്യുക"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"തുടരാൻ, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ആപ്പിന് നിങ്ങളുടെ ഉപകരണത്തിന്റെ മൈക്രോഫോണിലേക്ക് ആക്‌സസ് നൽകേണ്ടതുണ്ട്."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"തുടരാൻ, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ആപ്പിന് നിങ്ങളുടെ ഉപകരണത്തിന്റെ ക്യാമറയിലേക്ക് ആക്‌സസ് നൽകേണ്ടതുണ്ട്."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ഓണാക്കുക"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"സെൻസർ സ്വകാര്യത"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ആപ്പ് ഐക്കൺ"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"അപ്ലിക്കേഷൻ ബ്രാൻഡിംഗ് ഇമേജ്"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 71c52680b4b6..87b9958e311b 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -303,7 +303,7 @@
<string name="android_system_label" msgid="5974767339591067210">"Андройд систем"</string>
<string name="user_owner_label" msgid="8628726904184471211">"Хувийн профайл руу сэлгэх"</string>
<string name="managed_profile_label" msgid="7316778766973512382">"Ажлын профайл руу сэлгэх"</string>
- <string name="permgrouplab_contacts" msgid="4254143639307316920">"Харилцагчдын хаяг"</string>
+ <string name="permgrouplab_contacts" msgid="4254143639307316920">"Харилцагчид"</string>
<string name="permgroupdesc_contacts" msgid="9163927941244182567">"харилцагч руугаа хандах"</string>
<string name="permgrouplab_location" msgid="1858277002233964394">"Байршил"</string>
<string name="permgroupdesc_location" msgid="1995955142118450685">"энэ төхөөрөмжийн байршилд хандалт хийх"</string>
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"таны биеийн дасгал хөдөлгөөнд хандах"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Камер"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"зураг авах, бичлэг хийх"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Ойролцоох Bluetooth төхөөрөмжүүд"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"ойролцоох Bluetooth төхөөрөмжүүдийг илрүүлж, холбогдох"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Ойролцоох төхөөрөмжүүд"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"ойролцоох төхөөрөмжүүдийг илрүүлж, холбогдох"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Дуудлагын жагсаалт"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"утасны дуудлагын жагсаалтыг унших болон бичих"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Утас"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Aппыг ойролцоох Bluetooth төхөөрөмжүүдийг илрүүлж, хослуулахыг зөвшөөрдөг"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"хослуулсан Bluetooth төхөөрөмжүүдэд холбогдох"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Аппыг хослуулсан Bluetooth төхөөрөмжүүдэд холбогдохыг зөвшөөрдөг"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"Ойролцоох Bluetooth төхөөрөмжүүдэд сурталчлах"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Аппад ойролцоох Bluetooth төхөөрөмжүүдэд сурталчлахыг зөвшөөрнө"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"ойролцоох ультра өргөн зурвасын төхөөрөмжүүдийн хоорондох холбоотой байрлалыг тодорхойлох"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Аппад ойролцоох ультра өргөн зурвасын төхөөрөмжүүдийн хоорондох холбоотой байрлалыг тодорхойлохыг зөвшөөрөх"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Сонгосон NFC төлбөрийн үйлчилгээний мэдээлэл"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Бүртгүүлсэн төхөөрөмж болон маршрутын хүрэх цэг зэрэг сонгосон nfc төлбөрийн үйлчилгээний мэдээллийг авахыг аппад зөвшөөрдөг."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ойролцоо талбарын холбоог удирдах"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Та одоо дэлгэцийнхээ хэсгийг томруулах боломжтой"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Тохиргоонд асаана уу"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Үл хэрэгсэх"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Үргэлжлүүлэхийн тулд, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; таны төхөөрөмжийн микрофонд хандах шаардлагатай."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Үргэлжлүүлэхийн тулд &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; таны төхөөрөмжийн камерт хандах шаардлагатай."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Асаах"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Төхөөрөмжийн микрофоныг блокоос гаргах"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Төхөөрөмжийн камерыг блокоос гаргах"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; болон бүх апп, үйлчилгээнд"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Блокоос гаргах"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Мэдрэгчийн нууцлал"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Аппын дүрс тэмдэг"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Аппын брэнд зураг"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index fec8804292d7..89c7ebd799e0 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"शारीरिक अ‍ॅक्टिव्हिटी अ‍ॅक्सेस करा"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"कॅमेरा"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"चित्रे काढण्याची आणि व्हिडिओ रेकॉर्ड करण्याची"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"जवळपासची ब्लूटूथ डिव्‍हाइस"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"जवळपासची ब्लूटूथ डिव्‍हाइस शोधा आणि ती कनेक्ट करा"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"जवळपासची डीव्‍हाइस"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"जवळपास असलेली डिव्हाइस शोध आणि त्यांच्याशी कनेक्ट करा"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"कॉल लॉग"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"फोन कॉल लॉग वाचा आणि लिहा"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"फोन"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ॲपला जवळपासची ब्लूटूथ डिव्‍हाइस शोधण्यासाठी आणि ती पेअर करण्यासाठी अनुमती देते"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"पेअर केलेल्या ब्लूटूथ डिव्‍हाइसशी कनेक्ट करा"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"पेअर केलेल्या ब्लूटूथ डिव्‍हाइसशी कनेक्ट करण्यासाठी ॲपला अनुमती द्या"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"जवळच्या अल्ट्रा-वाइडबँड डिव्हाइसदरम्यानचे संबंधित स्थान निर्धारित करा"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ॲपला जवळच्या अल्ट्रा-वाइडबँड डिव्हाइसदरम्यानचे संबंधित स्थान निर्धारित करण्याची अनुमती द्या"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"प्राधान्यकृत NFC पेमेंट सेवा माहिती"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"नोंदणीकृत एड्स आणि मार्ग गंतव्यस्थान सारखी प्राधान्यकृत एनएफसी पेमेंट सेवेची माहिती मिळवण्यासाठी अ‍ॅपला अनुमती देते."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"फील्ड जवळील कम्युनिकेशन नियंत्रित करा"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"आता तुम्ही तुमच्या स्क्रीनचा एखादा भाग मॅग्निफाय करू शकता"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"सेटिंग्ज मध्ये सुरू करा"</string>
<string name="dismiss_action" msgid="1728820550388704784">"डिसमिस करा"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"पुढे सुरू ठेवण्यासाठी, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ला तुमच्या डिव्हाइसचा मायक्रोफोन अ‍ॅक्सेस करण्याची आवश्यकता आहे."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"पुढे सुरू ठेवण्यासाठी, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ला तुमच्या डिव्हाइसचा कॅमेरा अ‍ॅक्सेस करण्याची आवश्यकता आहे."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"सुरू करा"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"सेन्सरशी संबंधित गोपनीयतेबाबत सूचना"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ॲप्लिकेशन आयकन"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"अ‍ॅप्लिकेशन ब्रॅंडिंग इमेज"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 7f4f430229bd..09c6edca151e 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"akses aktiviti fizikal anda"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ambil gambar dan rakam video"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Peranti Bluetooth yang Berdekatan"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"temukan dan sambung kepada peranti Bluetooth yang berdekatan"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Peranti berdekatan"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"temukan dan sambung kepada peranti yang berdekatan"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Log panggilan"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"baca dan tulis log panggilan telefon"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Membenarkan apl menemukan dan berganding dengan peranti Bluetooth yang berdekatan"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"sambung kepada peranti Bluetooth yang digandingkan"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Membenarkan apl untuk menyambung kepada peranti Bluetooth yang digandingkan"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"tentukan kedudukan relatif antara peranti Ultrajalur Lebar berdekatan"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Benarkan apl menentukan kedudukan relatif antara peranti Ultrajalur Lebar berdekatan"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Maklumat Perkhidmatan Pembayaran NFC Pilihan"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Membenarkan apl mendapatkan maklumat perkhidmatan pembayaran nfc pilihan seperti bantuan berdaftar dan destinasi laluan."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"mengawal Komunikasi Medan Dekat"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Kini anda boleh membesarkan sebahagian skrin anda"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Hidupkan dalam Tetapan"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Tolak"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Hidupkan"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privasi Penderia"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikon aplikasi"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imej jenama aplikasi"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 5885136c53dd..944bf87fccf5 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"သင့်ကိုယ်လက်လှုပ်ရှားမှုကို ဝင်ကြည့်ရန်"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"ကင်မရာ"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ဓာတ်ပုံ ရိုက်ပြီးနောက် ဗွီဒီယို မှတ်တမ်းတင်ရန်"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"အနီးတစ်ဝိုက်ရှိ ဘလူးတုသ်သုံးစက်များ"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"အနီးတစ်ဝိုက်ရှိ ဘလူးတုသ်သုံးစက်များကို ရှာဖွေပြီးချိတ်ဆက်မည်"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"အနီးတစ်ဝိုက်ရှိ စက်များ"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"အနီးတစ်ဝိုက်ရှိ စက်များကို ရှာဖွေပြီးချိတ်ဆက်မည်"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"ခေါ်ဆိုမှတ်တမ်း"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ဖုန်းခေါ်ဆိုထားသော မှတ်တမ်း ဖတ်ပြီး ရေးရန်"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ဖုန်း"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"အနီးတစ်ဝိုက်ရှိ ဘလူးတုသ်သုံးစက်များကို ရှာဖွေပြီးတွဲချိတ်ရန် အက်ပ်ကိုခွင့်ပြုမည်"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"တွဲချိတ်ထားသော ဘလူးတုသ်စက်များနှင့် ချိတ်ဆက်ခြင်း"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"တွဲချိတ်ထားသော ဘလူးတုသ်သုံးစက်များနှင့် ချိတ်ဆက်ရန် အက်ပ်ကိုခွင့်ပြုမည်"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"အနီးတစ်ဝိုက်ရှိ ဘလူးတုသ်သုံးစက်များတွင် ကြော်ငြာခြင်း"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"အနီးတစ်ဝိုက်ရှိ ဘလူးတုသ်သုံးစက်များတွင် ကြော်ငြာရန် အက်ပ်အား ခွင့်ပြုမည်"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"အနီးတစ်ဝိုက်ရှိ ‘အလွန်ကျယ်ပြန့်သော လှိုင်းအလျားသုံးစက်များ’ ကြား ဆက်စပ်နေရာကို သတ်မှတ်ခြင်း"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"အနီးတစ်ဝိုက်ရှိ ‘အလွန်ကျယ်ပြန့်သော လှိုင်းအလျားသုံးစက်များ’ ကြား ဆက်စပ်နေရာကို သတ်မှတ်ရန် အက်ပ်ကို ခွင့်ပြုမည်"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ဦးစားပေး NFC ငွေပေးချေမှုဆိုင်ရာ ဝန်ဆောင်မှု အချက်အလက်များ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"အက်ပ်အား ဦစားပေး NFC ငွေပေးချေမှုဆိုင်ရာ ဝန်ဆောင်မှု အချက်အလက်များဖြစ်သည့် မှတ်ပုံတင်ထားသော အကူအညီများနှင့် သွားလာရာ လမ်းကြောင်းတို့ကို ရယူရန် ခွင့်ပြုသည်။"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communicationအား ထိန်းချုပ်ရန်"</string>
@@ -1285,12 +1285,12 @@
<string name="volume_unknown" msgid="4041914008166576293">"အသံအတိုးအကျယ်"</string>
<string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"ဘလူးတုသ်သံအတိုးအကျယ်"</string>
<string name="volume_icon_description_ringer" msgid="2187800636867423459">"ဖုန်းမြည်သံအတိုးအကျယ်"</string>
- <string name="volume_icon_description_incall" msgid="4491255105381227919">"ခေါ်ဆိုနေခြင်းအသံအတိုးအကျယ်"</string>
+ <string name="volume_icon_description_incall" msgid="4491255105381227919">"ဖုန်းခေါ်သံအတိုးအကျယ်"</string>
<string name="volume_icon_description_media" msgid="4997633254078171233">"မီဒီယာအသံအတိုးအကျယ်"</string>
<string name="volume_icon_description_notification" msgid="579091344110747279">"အကြောင်းကြားသံအတိုးအကျယ်"</string>
<string name="ringtone_default" msgid="9118299121288174597">"မူရင်းမြည်သံ"</string>
<string name="ringtone_default_with_actual" msgid="2709686194556159773">"မူရင်း (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
- <string name="ringtone_silent" msgid="397111123930141876">"တစ်ခုမျှမဟုတ်"</string>
+ <string name="ringtone_silent" msgid="397111123930141876">"မရှိ"</string>
<string name="ringtone_picker_title" msgid="667342618626068253">"မြည်သံများ"</string>
<string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"နှိုးစက်သံ"</string>
<string name="ringtone_picker_title_notification" msgid="6387191794719608122">"အကြောင်းကြားချက်အသံ"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"ဖန်သားပြင်တစ်စိတ်တစ်ပိုင်းကို ယခုချဲ့နိုင်ပါပြီ"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"\'ဆက်တင်များ\' တွင် ဖွင့်ရန်"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ပယ်ရန်"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ဆက်လက်လုပ်ဆောင်ရန် &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; က သင့်စက်၏ မိုက်ခရိုဖုန်းကို အသုံးပြုခွင့်ရရန် လိုအပ်သည်။"</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"ဆက်လက်လုပ်ဆောင်ရန် &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; က သင့်စက်၏ ကင်မရာကို အသုံးပြုခွင့်ရရန် လိုအပ်သည်။"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ဖွင့်ရန်"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"စက်၏မိုက်ခရိုဖုန်းကို ပြန်ဖွင့်ရန်"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"စက်၏ကင်မရာကို ပြန်ဖွင့်ရန်"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;၊ အက်ပ်နှင့် ဝန်ဆောင်မှုအားလုံးအတွက်"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"ပြန်ဖွင့်ရန်"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"အာရုံခံကိရိယာ လုံခြုံရေး"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"အပလီကေးရှင်း သင်္ကေတ"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"အပလီကေးရှင်း ကုန်အမှတ်တံဆိပ်ပုံ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 526fb85900ed..d7ad0a6b4caa 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"tilgang til den fysiske aktiviteten din"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ta bilder og ta opp video"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Bluetooth-enheter i nærheten"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"oppdage og koble til Bluetooth-enheter i nærheten"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Enheter i nærheten"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"oppdage og koble til enheter i nærheten"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Samtalelogger"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"lese og skrive samtaleloggen"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Lar appen oppdage og koble til Bluetooth-enheter i nærheten"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"koble til tilkoblede Bluetooth-enheter"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Lar appen koble til tilkoblede Bluetooth-enheter"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"vise til Bluetooth-enheter i nærheten"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Lar appen vise annonser til Bluetooth-enheter i nærheten"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"fastslå relativ posisjon mellom enheter som bruker ultrabredbånd"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"tillate at appen fastslår den relative posisjonen mellom enheter i nærheten som bruker ultrabredbånd"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informasjon om prioritert NFC-betalingstjeneste"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Gir appen tilgang til informasjon om prioritert NFC-betalingstjeneste, for eksempel registrerte hjelpemidler og destinasjon."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontroller overføring av data med NFC-teknologi"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Nå kan du forstørre en del av skjermen"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Slå på i innstillingene"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Avvis"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"For å fortsette må &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ha tilgang til enhetskameraet."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Slå på"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Opphev blokkeringen av enhetsmikrofonen"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Opphev blokkeringen av enhetskameraet"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"For &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; og alle apper og tjenester"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Opphev blokkeringen"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorpersonvern"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Appikon"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Merkevareprofilen til appen"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 1c2c2abdbc7d..0eeb5480fc57 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -320,9 +320,11 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"आफ्नो शारीरिक क्रियाकलापको डेटामाथि पहुँच राख्नु"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"क्यामेरा"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"फोटो खिच्नुका साथै भिडियो रेकर्ड गर्नुहोस्"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"नजिकै रहेका ब्लुटुथ चल्ने यन्त्रहरू"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"नजिकै रहेका ब्लुटुथ चल्ने यन्त्रहरू भेट्टाउने र ती यन्त्रहरूसँग कनेक्ट गर्ने"</string>
- <string name="permgrouplab_calllog" msgid="7926834372073550288">"कलका लगहरू"</string>
+ <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
+ <skip />
+ <string name="permgrouplab_calllog" msgid="7926834372073550288">"कल लग"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"फोन कलको लग पढ्नुहोस् र लेख्नुहोस्"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"फोन"</string>
<string name="permgroupdesc_phone" msgid="270048070781478204">"फोन कलहरू गर्नुहोस् र व्यवस्थापन गर्नुहोस्"</string>
@@ -360,7 +362,7 @@
<string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"एपलाई आगमन फोन कलको जवाफ दिन अनुमति दिन्छ।"</string>
<string name="permlab_receiveSms" msgid="505961632050451881">"टेक्स्ट म्यासेजहरू (SMS) प्राप्त गर्नुहोस्"</string>
<string name="permdesc_receiveSms" msgid="1797345626687832285">"एपलाई SMS सन्देशहरू प्राप्त गर्न र प्रक्रिया गर्न अनुमति दिन्छ। यसको मतलब अनुप्रयोगले तपाईंको उपकरणमा पठाइएको सन्देशहरू तपाईंलाई नदेखाईनै मोनिटर गर्न वा मेटाउन सक्दछ।"</string>
- <string name="permlab_receiveMms" msgid="4000650116674380275">"पाठ सन्देश (MMS) प्राप्त गर्नुहोस्"</string>
+ <string name="permlab_receiveMms" msgid="4000650116674380275">"टेक्स्ट म्यासेज (MMS) प्राप्त गर्नुहोस्"</string>
<string name="permdesc_receiveMms" msgid="958102423732219710">"एपलाई MMS सन्देशहरू प्राप्त गर्न र प्रकृया गर्न अनुमति दिन्छ। यसको मतलब अनुप्रयोगले तपाईंको उपकरणमा पठाइएको सन्देशहरू तपाईंलाई नदेखाईनै मोनिटर गर्न वा मेटाउन सक्दछ।"</string>
<string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"मोबाइल प्रसारणसम्बन्धी सन्देशहरू फर्वार्ड गर्नुहोस्"</string>
<string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"मोबाइल प्रसारणसम्बन्धी सन्देशहरू प्राप्त हुनासाथै तिनीहरूलाई फर्वार्ड गर्नका लागि यसले एपलाई मोबाइल प्रसारण मोड्युलमा जोडिने अनुमति दिन्छ। तपाईंलाई कतिपय स्थानमा आपत्‌कालीन अवस्थाका बारेमा जानकारी दिनका लागि मोबाइल प्रसारणसम्बन्धी अलर्टहरू पठाइन्छ। हानिकारक एपहरूले आपत्‌कालीन मोबाइल प्रसारण प्राप्त हुँदा तपाईंको यन्त्रलाई कार्य सम्पादन गर्ने वा सञ्चालित हुने क्रममा हस्तक्षेप गर्न सक्छन्।"</string>
@@ -413,9 +415,9 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"एपलाई प्रसारण समाप्त भइसकेपछि पनि रहिरहने स्टिकी प्रसारणहरू पठाउने अनुमति दिन्छ। यो सुविधाको अत्यधिक प्रयोगले धेरै मेमोरी प्रयोग हुने भएकाले तपाईंको Android टिभी यन्त्र सुस्त वा अस्थिर हुन सक्छ।"</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"औपचारिक प्रसारणलाई पठाउनको लागि एक एपलाई अनुमति दिन्छ, जुन प्रसारण समाप्त भएपछि बाँकी रहन्छ। अत्यधिक प्रयोगले धेरै मेमोरी प्रयोग गरेको कारणले फोनलाई ढिलो र अस्थिर बनाउन सक्छ।"</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"तपाईँका सम्पर्कहरू पढ्नुहोस्"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"एपलाई तपाईंको ट्याब्लेटमा भण्डार गरिएका सम्पर्क ठेगानाहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको ट्याब्लेटमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले एपहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
- <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"एपलाई तपाईंको Android टिभी डिभाइसमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा पढ्न अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको Android टिभी डिभाइसमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले एपहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
- <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"एपलाई तपाईंको फोनमा भण्डार गरिएका सम्पर्क ठेगानाहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको फोनमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले एपहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सुरक्षित गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"एपलाई तपाईंको ट्याब्लेटमा भण्डार गरिएका सम्पर्क ठेगानाहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको ट्याब्लेटमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले एपहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सेभ गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"एपलाई तपाईंको Android टिभी डिभाइसमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा पढ्न अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको Android टिभी डिभाइसमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले एपहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सेभ गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"एपलाई तपाईंको फोनमा भण्डार गरिएका सम्पर्क ठेगानाहरूसँग सम्बन्धित डेटा पढ्ने अनुमति दिन्छ। एपहरूले सम्पर्क ठेगानाहरू बनाउने तपाईंको फोनमा भण्डार गरिएका खाताहरूमाथि पनि पहुँच प्राप्त गर्ने छन्। यसमा तपाईंले स्थापना गरेका एपहरूले बनाएका खाताहरू पर्न सक्छन्। यस अनुमतिले एपहरूलाई तपाईंको सम्पर्क ठेगानासम्बन्धी डेटा सेभ गर्न दिने भएकाले हानिकारक एपहरूले तपाईंलाई थाहै नदिइकन सम्पर्क ठेगानासम्बन्धी डेटा आदान प्रदान गर्न सक्छन्।"</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"तपाईँका सम्पर्कहरू परिवर्तन गर्नुहोस्"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"एपलाई तपाईंको ट्याब्लेटमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा परिमार्जन गर्न अनुमति दिन्छ। यो अनुमतिले एपलाई सम्पर्क ठेगानासम्बन्धी डेटा मेटाउन अनुमति दिन्छ।"</string>
<string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"एपलाई तपाईंको Android टिभी डिभाइसमा भण्डारण गरिएका सम्पर्क ठेगानासम्बन्धी डेटा परिमार्जन गर्न अनुमति दिन्छ। यो अनुमतिले एपलाई सम्पर्क ठेगानासम्बन्धी डेटा मेटाउन अनुमति दिन्छ।"</string>
@@ -535,10 +537,14 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"ट्याब्लेटमा ब्लुटुथको कन्फिगुरेसनलाई हेर्न र बनाउन र जोडी उपकरणहरूसँग जडानहरूलाई स्वीकार गर्न एपलाई अनुमति दिन्छ।"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"एपलाई तपाईंको Android टिभी डिभाइसको ब्लुटुथको कन्फिगुरेसन हेर्ने तथा जोडा बनाइएका यन्त्रहरूसँग जोडिने वा ती यन्त्रहरूले पठाएका जोडिने अनुरोध स्वीकार्ने अनुमति दिन्छ।"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"एपलाई फोनमा ब्लुटुथको कन्फिगरेसन हेर्न र जोडी भएका उपकरणहरूसँग जडानहरू बनाउन र स्वीकार गर्न अनुमति दिन्छ।"</string>
- <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"नजिकै रहेका ब्लुटुथ चल्ने यन्त्रहरू भेट्टाउने र ती यन्त्रहरूसँग कनेक्ट गर्ने"</string>
- <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"यो अनुमति दिइएमा एपले नजिकै रहेका ब्लुटुथ चल्ने यन्त्रहरू भेट्टाउन र ती यन्त्रहरूसँग कनेक्ट गर्न सक्छ"</string>
+ <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"नजिकै रहेका ब्लुटुथ चल्ने डिभाइसहरू भेट्टाउने र ती यन्त्रहरूसँग कनेक्ट गर्ने"</string>
+ <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"यो अनुमति दिइएमा एपले नजिकै रहेका ब्लुटुथ चल्ने डिभाइसहरू भेट्टाउन र ती यन्त्रहरूसँग कनेक्ट गर्न सक्छ"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"लिंक गरिएका ब्लुटुथ चल्ने यन्त्रहरूसँग कनेक्ट गर्ने"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"यो अनुमति दिइएमा एपले लिंक गरिएका ब्लुटुथ चल्ने यन्त्रहरूसँग कनेक्ट गर्न सक्छ"</string>
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
+ <skip />
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
+ <skip />
<!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
<skip />
<!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
@@ -577,8 +583,7 @@
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"कुनै पनि PIN, ढाँचा वा पासवर्ड सेट गरिएको छैन"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"प्रमाणित गर्ने क्रममा त्रुटि भयो"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"स्क्रिन लक प्रयोग गर्नुहोस्"</string>
- <!-- no translation found for screen_lock_dialog_default_subtitle (120359538048533695) -->
- <skip />
+ <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"जारी राख्न आफ्नो स्क्रिन लक हाल्नुहोस्"</string>
<!-- no translation found for fingerprint_acquired_partial (694598777291084823) -->
<skip />
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"फिंगरप्रिन्ट प्रशोधन गर्न सकिएन। कृपया फेरि प्रयास गर्नुहोस्।"</string>
@@ -665,8 +670,7 @@
<string name="face_name_template" msgid="3877037340223318119">"अनुहार <xliff:g id="FACEID">%d</xliff:g>"</string>
<string name="face_app_setting_name" msgid="8130135875458467243">"फेस अनलक प्रयोग गर्नुहोस्"</string>
<string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"फेस अनलक वा स्क्रिन लक प्रयोग गर्नुहोस्"</string>
- <!-- no translation found for face_dialog_default_subtitle (6620492813371195429) -->
- <skip />
+ <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"जारी राख्न आफ्नो अनुहारको सहायताले पुष्टि गर्नुहोस्"</string>
<string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"जारी राख्न आफ्नो फेस वा स्क्रिन लक प्रयोग गरी पुष्टि गर्नुहोस्"</string>
<string-array name="face_error_vendor">
</string-array>
@@ -940,7 +944,7 @@
<string name="lockscreen_glogin_password_hint" msgid="3031027901286812848">"पासवर्ड:"</string>
<string name="lockscreen_glogin_submit_button" msgid="3590556636347843733">"साइन इन गर्नुहोस्"</string>
<string name="lockscreen_glogin_invalid_input" msgid="4369219936865697679">"अमान्य प्रयोगकर्तानाम वा पासवर्ड"</string>
- <string name="lockscreen_glogin_account_recovery_hint" msgid="1683405808525090649">"तपाईँको एक-पटके पाठ सन्देश वा पासवर्ड बिर्सनुभयो?\n भ्रमण गर्नुहोस"<b>"google.com/accounts/recovery"</b></string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="1683405808525090649">"तपाईँको एक-पटके टेक्स्ट म्यासेज वा पासवर्ड बिर्सनुभयो?\n भ्रमण गर्नुहोस"<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="2607271802803381645">"जाँच गर्दै..."</string>
<string name="lockscreen_unlock_label" msgid="4648257878373307582">"खोल्नुहोस्"</string>
<string name="lockscreen_sound_on_label" msgid="1660281470535492430">"आवाज चालु छ।"</string>
@@ -1372,7 +1376,7 @@
<string name="usb_midi_notification_title" msgid="7404506788950595557">"USB मार्फत MIDI सेवा सक्रिय गरियो"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB सहायक उपकरण जडान गरियो"</string>
<string name="usb_notification_message" msgid="4715163067192110676">"थप विकल्पहरूका लागि ट्याप गर्नुहोस्।"</string>
- <string name="usb_power_notification_message" msgid="7284765627437897702">"जडान गरिएको यन्त्र चार्ज गर्दै। थप विकल्पहरूका लागि ट्याप गर्नुहोस्।"</string>
+ <string name="usb_power_notification_message" msgid="7284765627437897702">"कनेक्ट गरिएको डिभाइस चार्ज गर्दै। थप विकल्पहरूका लागि ट्याप गर्नुहोस्।"</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"एनालग अडियोको सहायक उपकरण पत्ता लाग्यो"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"संलग्न गरिएको यन्त्र यो फोनसँग कम्प्याटिबल छैन। थप जान्न ट्याप गर्नुहोस्।"</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"USB डिबगिङ सक्रिय गरिएको छ"</string>
@@ -1583,7 +1587,7 @@
<string name="storage_usb_drive_label" msgid="6631740655876540521">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB ड्राइभ"</string>
<string name="storage_usb" msgid="2391213347883616886">"USB भण्डारण"</string>
<string name="extract_edit_menu_button" msgid="63954536535863040">"सम्पादन गर्नुहोस्"</string>
- <string name="data_usage_warning_title" msgid="9034893717078325845">"डेटासम्बन्धी चेतावनी"</string>
+ <string name="data_usage_warning_title" msgid="9034893717078325845">"डेटाको खपतसम्बन्धी चेतावनी"</string>
<string name="data_usage_warning_body" msgid="1669325367188029454">"तपाईंले <xliff:g id="APP">%s</xliff:g> डेटा प्रयोग गर्नुभयो"</string>
<string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"मोबाइल डेटाको अधिकतम सीमा पुगेको छ"</string>
<string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"Wi-Fi डेटा सीमा पुग्यो"</string>
@@ -1634,7 +1638,7 @@
<string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"स्क्रिन उपकरणमा कास्ट गर्नुहोस्"</string>
<string name="media_route_chooser_searching" msgid="6119673534251329535">"उपकरणको खोजी गरिँदै..."</string>
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"सेटिंङहरू"</string>
- <string name="media_route_controller_disconnect" msgid="7362617572732576959">"विच्छेदन गर्नुहोस्"</string>
+ <string name="media_route_controller_disconnect" msgid="7362617572732576959">"डिस्कनेक्ट गर्नुहोस्"</string>
<string name="media_route_status_scanning" msgid="8045156315309594482">"स्क्यान गर्दै ..."</string>
<string name="media_route_status_connecting" msgid="5845597961412010540">"जडान हुँदै..."</string>
<string name="media_route_status_available" msgid="1477537663492007608">"उपलब्ध"</string>
@@ -1668,7 +1672,7 @@
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"PIN कोडहरू मेल खाएन"</string>
<string name="kg_login_too_many_attempts" msgid="699292728290654121">"निकै धेरै ढाँचा कोसिसहरू"</string>
<string name="kg_login_instructions" msgid="3619844310339066827">"अनलक गर्नको लागि, तपाईँको Google खाताको साथ साइन इन गर्नुहोस्।"</string>
- <string name="kg_login_username_hint" msgid="1765453775467133251">"एक-पटके पाठ सन्देश (इमेल)"</string>
+ <string name="kg_login_username_hint" msgid="1765453775467133251">"एक-पटके टेक्स्ट म्यासेज (इमेल)"</string>
<string name="kg_login_password_hint" msgid="3330530727273164402">"पासवर्ड"</string>
<string name="kg_login_submit_button" msgid="893611277617096870">"साइन इन गर्नुहोस्"</string>
<string name="kg_login_invalid_input" msgid="8292367491901220210">"अमान्य प्रयोगकर्तानाम वा पासवर्ड।"</string>
@@ -1864,7 +1868,7 @@
<string name="confirm_battery_saver" msgid="5247976246208245754">"ठिक छ"</string>
<string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"ब्याट्री सेभरले डिभाइसको ब्याट्री बढी समय टिकाउन:\n\n•अँध्यारो थिम सक्रिय गर्छ\n•पृष्ठभूमिका गतिविधि, केही दृश्यात्मक प्रभाव तथा “Hey Google” जस्ता अन्य सुविधाहरू निष्क्रिय वा सीमित पार्छ\n\n"<annotation id="url">"थप जान्नुहोस्"</annotation></string>
<string name="battery_saver_description" msgid="6794188153647295212">"ब्याट्री सेभरले डिभाइसको ब्याट्री बढी समय टिकाउन:\n\n• अँध्यारो थिम अन गर्छ\n• पृष्ठभूमिका क्रियाकलाप, केही दृश्यात्मक प्रभाव तथा “Hey Google” जस्ता अन्य सुविधाहरू अफ गर्छ वा सीमित पार्छ"</string>
- <string name="data_saver_description" msgid="4995164271550590517">"डेटाको प्रयोगलाई कम गर्न डेटा सर्भरले केही एपलाई पृष्ठभूमिमा डेटा पठाउन वा प्राप्त गर्न दिँदैन। तपाईंले हाल प्रयोग गरिरहनुभएको अनु्प्रयोगले डेटा चलाउन सक्छ, तर पहिला भन्दा कम अन्तरालमा मात्र। उदाहरणका लागि, तपाईले छविहरूमा ट्याप नगरेसम्म ती छविहरू देखिँदैनन्।"</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"डेटा सेभरले डेटा खपत कम गर्न केही एपहरूलाई ब्याकग्राउन्डमा डेटा पठाउन वा प्राप्त गर्न दिँदैन। तपाईंले अहिले प्रयोग गरिरहनुभएको एपले सीमित रूपमा मात्र डेटा चलाउन पाउँछ। उदाहरणका लागि, तपाईंले फोटोमा ट्याप गर्नुभयो भने मात्र फोटो देखिन्छ नत्र देखिँदैन।"</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"डेटा सेभर सक्रिय गर्ने हो?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"सक्रिय गर्नुहोस्"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
@@ -2269,9 +2273,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"तपाईं अब स्क्रिनको जुनसुकै भाग जुम इन गर्न सक्नुहुन्छ"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"सेटिङमा गई यो सुविधा अन गर्नुहोस्"</string>
<string name="dismiss_action" msgid="1728820550388704784">"हटाउनुहोस्"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"जारी राख्न &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; लाई तपाईंको डिभाइसको माइक्रोफोन प्रयोग गर्ने अनुमति दिनु पर्ने हुन्छ।"</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"जारी राख्न &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; लाई तपाईंको डिभाइसको क्यामेरा प्रयोग गर्ने अनुमति दिनु पर्ने हुन्छ।"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"अन गर्नुहोस्"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"सेन्सरसम्बन्धी गोपनीयता"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"एप जनाउने आइकन"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"एपको ब्रान्डिङ फोटो"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 95edb6425c0a..e9beecec7466 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"toegang tot je fysieke activiteit"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Camera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"foto\'s maken en video opnemen"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Bluetooth-apparaten in de buurt"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"bluetooth-apparaten in de buurt vinden en er verbinding mee maken"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Apparaten in de buurt"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"apparaten in de buurt vinden en er verbinding mee maken"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Gesprekslijsten"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"gesprekslijst lezen en schrijven"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefoon"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Hiermee kan de app bluetooth-apparaten in de buurt vinden en koppelen"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"verbinding maken met gekoppelde bluetooth-apparaten"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Hiermee kan de app verbinding maken met gekoppelde bluetooth-apparaten"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"adverteren op bluetooth-apparaten in de buurt"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Hiermee kan de app adverteren op bluetooth-apparaten in de buurt"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"relatieve positie tussen ultrabreedbandapparaten in de buurt bepalen"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"De app toestaan om de relatieve positie tussen ultrabreedbandapparaten in de buurt te bepalen"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informatie over voorkeursservice voor NFC-betaling"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Hiermee kun je zorgen dat de app informatie krijgt over de voorkeursservice voor NFC-betaling, zoals geregistreerde hulpmiddelen en routebestemmingen."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication regelen"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Je kunt nu een deel van je scherm vergroten"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aanzetten in Instellingen"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Sluiten"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"&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_notification_content" msgid="4738005643315863736">"&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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aanzetten"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Blokkeren van apparaatmicrofoon opheffen"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Blokkeren van apparaatcamera opheffen"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Voor &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; en alle andere apps en services"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Blokkeren opheffen"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorprivacy"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"App-icoon"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Merkafbeelding voor app"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 487b8a57f83b..1bcd20eaee9d 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ଆପଣଙ୍କ ଶାରୀରିକ କାର୍ଯ୍ୟକଳାପ ଆକ୍ସେସ୍ କରନ୍ତୁ"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"କ୍ୟାମେରା"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ଫଟୋ ନିଏ ଓ ଭିଡିଓ ରେକର୍ଡ କରେ"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"ଆଖପାଖର ବ୍ଲୁଟୁଥ୍ ଡିଭାଇସଗୁଡ଼ିକ"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"ଆଖପାଖର ବ୍ଲୁଟୁଥ୍ ଡିଭାଇସଗୁଡ଼ିକୁ ଖୋଜି ସଂଯୋଗ କରନ୍ତୁ"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"ଆଖପାଖର ଡିଭାଇସଗୁଡ଼ିକ"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"ଆଖପାଖର ଡିଭାଇସଗୁଡ଼ିକୁ ଖୋଜି ସଂଯୋଗ କରନ୍ତୁ"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"କଲ୍‌ ଲଗ୍‌"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ଫୋନ୍‌ କଲ୍‌ ଲଗ୍‌ ପଢ଼ନ୍ତୁ ଓ ଲେଖନ୍ତୁ"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ଫୋନ୍‍"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ଆଖପାଖର ବ୍ଲୁଟୁଥ୍ ଡିଭାଇସଗୁଡ଼ିକୁ ଖୋଜି ପେୟାର୍ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ପେୟାର୍ କରାଯାଇଥିବା ବ୍ଲୁଟୁଥ୍ ଡିଭାଇସଗୁଡ଼ିକ ସହ ସଂଯୋଗ କର"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ପେୟାର୍ କରାଯାଇଥିବା ବ୍ଲୁଟୁଥ୍ ଡିଭାଇସଗୁଡ଼ିକ ସହ ସଂଯୋଗ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"ଆଖପାଖର ବ୍ଲୁଟୁଥ୍ ଡିଭାଇସଗୁଡ଼ିକରେ ବିଜ୍ଞାପନ ଦିଅନ୍ତୁ"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"ଆଖପାଖର ବ୍ଲୁଟୁଥ୍ ଡିଭାଇସଗୁଡ଼ିକରେ ବିଜ୍ଞାପନ ଦେବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"ଆଖପାଖର ଅଲଟ୍ରା-ୱାଇଡବ୍ୟାଣ୍ଡ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପେକ୍ଷିକ ଅବସ୍ଥିତିକୁ ନିର୍ଦ୍ଧାରଣ କର"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ଆଖପାଖର ଅଲଟ୍ରା-ୱାଇଡବ୍ୟାଣ୍ଡ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପେକ୍ଷିକ ଅବସ୍ଥିତିକୁ ନିର୍ଦ୍ଧାରଣ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ପସନ୍ଦର NFC ପେମେଣ୍ଟ ସେବା ସୂଚନା"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ପଞ୍ଜିକୃତ ଯନ୍ତ୍ର ଏବଂ ମାର୍ଗ ଲକ୍ଷସ୍ଥଳ ପରି ପସନ୍ଦର nfc ପେମେଣ୍ଟ ସେବା ସୂଚନା ପାଇବାକୁ ଆପ୍ ଅନୁମତି କରିଥାଏ।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ନିଅର୍ ଫିଲ୍ଡ କମ୍ୟୁନିକେଶନ୍ ଉପରେ ନିୟନ୍ତ୍ରଣ ରଖନ୍ତୁ"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"ଆପଣ ଏବେ ଆପଣଙ୍କ ସ୍କ୍ରିନର ଅଂଶକୁ ମ୍ୟାଗ୍ନିଫାଏ କରିପାରିବେ"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ସେଟିଂସରେ ଚାଲୁ କରନ୍ତୁ"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ଖାରଜ କରନ୍ତୁ"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ଜାରି ରଖିବାକୁ, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ଆପଣଙ୍କ ଡିଭାଇସର ମାଇକ୍ରୋଫୋନକୁ ଆକ୍ସେସ୍ ଆବଶ୍ୟକ କରେ।"</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"ଜାରି ରଖିବାକୁ, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ଆପଣଙ୍କ ଡିଭାଇସର କ୍ୟାମେରାକୁ ଆକ୍ସେସ୍ ଆବଶ୍ୟକ କରେ।"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ଚାଲୁ କରନ୍ତୁ"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"ଡିଭାଇସର ମାଇକ୍ରୋଫୋନକୁ ଅନବ୍ଲକ୍ କରନ୍ତୁ"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"ଡିଭାଇସର କ୍ୟାମେରାକୁ ଅନବ୍ଲକ୍ କରନ୍ତୁ"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ଏବଂ ସମସ୍ତ ଆପ୍ ଓ ସେବା ପାଇଁ"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"ଅନବ୍ଲକ୍ କରନ୍ତୁ"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ସେନ୍ସର୍ ଗୋପନୀୟତା"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ଆପ୍ଲିକେସନ୍ ଆଇକନ୍"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ଆପ୍ଲିକେସନ୍ ବ୍ରାଣ୍ଡିଂ ଛବି"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 39fb734e86fc..ee19e0463cfb 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -319,8 +319,10 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ਆਪਣੀ ਸਰੀਰਕ ਸਰਗਰਮੀ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"ਕੈਮਰਾ"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ਤਸਵੀਰਾਂ ਲੈਣ ਅਤੇ ਵੀਡੀਓ ਰਿਕਾਰਡ ਕਰਨ"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"ਨਜ਼ਦੀਕੀ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"ਨਜ਼ਦੀਕੀ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਨੂੰ ਖੋਜੋ ਅਤੇ ਉਹਨਾਂ ਨਾਲ ਕਨੈਕਟ ਕਰੋ"</string>
+ <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
+ <skip />
<string name="permgrouplab_calllog" msgid="7926834372073550288">"ਕਾਲ ਲੌਗ"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ਫ਼ੋਨ ਦੇ ਕਾਲ ਲੌਗ ਨੂੰ ਪੜ੍ਹੋ ਅਤੇ ਲਿਖੋ"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ਫ਼ੋਨ"</string>
@@ -538,6 +540,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ਐਪ ਨੂੰ ਨਜ਼ਦੀਕੀ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਨੂੰ ਖੋਜਣ ਅਤੇ ਉਹਨਾਂ ਨਾਲ ਜੋੜਾਬੱਧ ਕਰਨ ਦਿੰਦੀ ਹੈ"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ਜੋੜਾਬੱਧ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਟ ਕਰੋ"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ਐਪਾਂ ਨੂੰ ਜੋੜਾਬੱਧ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਟ ਕਰਨ ਦਿੰਦੀ ਹੈ"</string>
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
+ <skip />
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
+ <skip />
<!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
<skip />
<!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
@@ -2259,9 +2265,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"ਹੁਣ ਤੁਸੀਂ ਆਪਣੀ ਸਕ੍ਰੀਨ ਦਾ ਕੁਝ ਹਿੱਸਾ ਵੱਡਦਰਸ਼ੀ ਕਰ ਸਕਦੇ ਹੋ"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਚਾਲੂ ਕਰੋ"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ਖਾਰਜ ਕਰੋ"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"ਜਾਰੀ ਰੱਖਣ ਲਈ, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ਨੂੰ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਤੱਕ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ।"</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"ਜਾਰੀ ਰੱਖਣ ਲਈ, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ਨੂੰ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੇ ਕੈਮਰਾ ਤੱਕ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ।"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ਚਾਲੂ ਕਰੋ"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ਸੈਂਸਰ ਪਰਦੇਦਾਰੀ"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ਐਪਲੀਕੇਸ਼ਨ ਪ੍ਰਤੀਕ"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ਐਪਲੀਕੇਸ਼ਨ ਦਾ ਬ੍ਰਾਂਡ ਵਾਲਾ ਚਿੱਤਰ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 3d1b19f6cfed..076b9660bcb9 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -325,8 +325,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"dostęp do aktywności fizycznej"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Aparat"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"robienie zdjęć i nagrywanie filmów"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Urządzenia Bluetooth w pobliżu"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"wykrywanie urządzeń Bluetooth w pobliżu i łączenie się z nimi"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Urządzenia w pobliżu"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"wykrywanie urządzeń w pobliżu i łączenie się z nimi"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Rejestry połączeń"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"odczytywanie i zapisywanie rejestru połączeń telefonicznych"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -544,10 +544,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Zezwala na wykrywanie i parowanie przez aplikację urządzeń Bluetooth w pobliżu"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"łączenie ze sparowanymi urządzeniami Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Zezwala na łączenie aplikacji ze sparowanymi urządzeniami Bluetooth"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"określanie względnego położenia urządzeń ultraszerokopasmowych w pobliżu"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Zezwól na określanie przez aplikację względnego położenia urządzeń ultraszerokopasmowych w pobliżu"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacje o preferowanych usługach płatniczych NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Pozwala aplikacji uzyskiwać informacje o preferowanych usługach płatniczych NFC, np. zarejestrowanych pomocach i miejscach docelowych tras."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolowanie łączności Near Field Communication"</string>
@@ -1395,14 +1397,14 @@
<string name="perm_costs_money" msgid="749054595022779685">"to może generować dodatkowe koszty"</string>
<string name="dlg_ok" msgid="5103447663504839312">"OK"</string>
<string name="usb_charging_notification_title" msgid="1674124518282666955">"Ładowanie urządzenia przez USB"</string>
- <string name="usb_supplying_notification_title" msgid="5378546632408101811">"Ładowanie podłączonego urządzenia przez USB"</string>
+ <string name="usb_supplying_notification_title" msgid="5378546632408101811">"Ładowanie połączonego urządzenia przez USB"</string>
<string name="usb_mtp_notification_title" msgid="1065989144124499810">"Przesyłanie plików przez USB włączone"</string>
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"Tryb PTP przez USB włączony"</string>
<string name="usb_tether_notification_title" msgid="8828527870612663771">"Tethering USB włączony"</string>
<string name="usb_midi_notification_title" msgid="7404506788950595557">"Tryb MIDI przez USB włączony"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"Podłączono akcesorium USB"</string>
<string name="usb_notification_message" msgid="4715163067192110676">"Kliknij, by wyświetlić więcej opcji."</string>
- <string name="usb_power_notification_message" msgid="7284765627437897702">"Ładowanie podłączonego urządzenia. Kliknij, by wyświetlić więcej opcji."</string>
+ <string name="usb_power_notification_message" msgid="7284765627437897702">"Ładowanie połączonego urządzenia. Kliknij, by wyświetlić więcej opcji."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Wykryto analogowe urządzenie audio"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Podłączone urządzenie nie jest zgodne z tym telefonem. Kliknij, by dowiedzieć się więcej."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"Podłączono moduł debugowania USB"</string>
@@ -2327,9 +2329,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Możesz teraz powiększyć część ekranu"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Włącz w Ustawieniach"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Odrzuć"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"Aby kontynuować, musisz przyznać aplikacji „<xliff:g id="APP">%s</xliff:g>” dostęp do aparatu urządzenia."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Włącz"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Poufność danych z czujników"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikacji"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Wizerunek marki aplikacji"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index da2c0e45c702..aedc5c312b07 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"acessar sua atividade física"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Câmera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"tire fotos e grave vídeos"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Dispositivos Bluetooth por perto"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"descobrir e se conectar a dispositivos Bluetooth por perto"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Dispositivos por perto"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"descobrir e se conectar a dispositivos por perto"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Registro de chamadas"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ler e gravar o registro de chamadas telefônicas"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefone"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que o app descubra e se pareie a dispositivos Bluetooth por perto"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"conecte-se a dispositivos Bluetooth pareados"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite que o app se conecte a dispositivos Bluetooth pareados"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"anunciar em dispositivos Bluetooth por perto"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite que o app seja anunciado em dispositivos Bluetooth por perto"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"determinar o posicionamento relativo entre dispositivos de banda ultralarga por perto"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permitir que o app determine o posicionamento relativo entre dispositivos de banda ultralarga por perto"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações preferidas de serviço de pagamento por NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que o app acesse as informações preferidas de serviço de pagamento por NFC, como auxílios registrados ou destinos de trajetos."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar a comunicação a curta distância"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Agora você pode ampliar parte da tela"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ativar nas Configurações"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Dispensar"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Para continuar, o app &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; precisa acessar o microfone do dispositivo."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Para continuar, o app &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; precisa acessar a câmera do dispositivo."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Ativar"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Desbloquear o microfone do dispositivo"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Desbloquear a câmera do dispositivo"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Para &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; e todos os apps e serviços"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Desbloquear"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidade do sensor"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ícone do aplicativo"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imagem da marca do aplicativo"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 1db483564a4a..537d7e2dead6 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"aceder à sua atividade física"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Câmara"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"tirar fotos e gravar vídeos"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Dispositivos Bluetooth próximos"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"descubra e ligue-se a dispositivos Bluetooth próximos"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Dispositivos próximos"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"descubra e estabeleça ligação a dispositivos próximos"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Registos de chamadas"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ler e escrever o registo de chamadas do telemóvel"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telemóvel"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que a app descubra e sincronize com dispositivos Bluetooth próximos"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ligar-se a dispositivos Bluetooth sincronizados"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite que a app se ligue a dispositivos Bluetooth sincronizados"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"mostrar anúncios a dispositivos Bluetooth próximos"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite que a app apresente anúncios a dispositivos Bluetooth próximos"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"determinar posição relativa dispos. de banda ultralarga próximos"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permita que a app determine a posição relativa entre os dispositivos de banda ultralarga próximos"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações de serviços de pagamento com NFC preferenciais"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que a app obtenha informações de serviços de pagamento com NFC preferenciais, como apoios registados e destino da rota."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlo Near Field Communication"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Já pode ampliar o ecrã parcialmente"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ativar nas Definições"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Ignorar"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Para continuar, a app &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; precisa de acesso ao microfone do dispositivo."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Para continuar, a app &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; precisa de acesso à câmara do dispositivo."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Ativar"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Desbloqueie o microfone do dispositivo"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Desbloqueie a câmara do dispositivo"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Para a app &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; e todas as apps e serviços"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Desbloquear"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidade dos sensores"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ícone de aplicação."</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imagem de branding da aplicação."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index da2c0e45c702..aedc5c312b07 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"acessar sua atividade física"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Câmera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"tire fotos e grave vídeos"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Dispositivos Bluetooth por perto"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"descobrir e se conectar a dispositivos Bluetooth por perto"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Dispositivos por perto"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"descobrir e se conectar a dispositivos por perto"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Registro de chamadas"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ler e gravar o registro de chamadas telefônicas"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefone"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que o app descubra e se pareie a dispositivos Bluetooth por perto"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"conecte-se a dispositivos Bluetooth pareados"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite que o app se conecte a dispositivos Bluetooth pareados"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"anunciar em dispositivos Bluetooth por perto"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite que o app seja anunciado em dispositivos Bluetooth por perto"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"determinar o posicionamento relativo entre dispositivos de banda ultralarga por perto"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permitir que o app determine o posicionamento relativo entre dispositivos de banda ultralarga por perto"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações preferidas de serviço de pagamento por NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que o app acesse as informações preferidas de serviço de pagamento por NFC, como auxílios registrados ou destinos de trajetos."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar a comunicação a curta distância"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Agora você pode ampliar parte da tela"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ativar nas Configurações"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Dispensar"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Para continuar, o app &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; precisa acessar o microfone do dispositivo."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Para continuar, o app &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; precisa acessar a câmera do dispositivo."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Ativar"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Desbloquear o microfone do dispositivo"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Desbloquear a câmera do dispositivo"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Para &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; e todos os apps e serviços"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Desbloquear"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidade do sensor"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ícone do aplicativo"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imagem da marca do aplicativo"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 5d581cd4625a..c4f0202d6d84 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -322,8 +322,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"accesați activitatea fizică"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Camera foto"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"fotografieze și să înregistreze videoclipuri"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Dispozitive Bluetooth din apropiere"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"să descopere și să se conecteze la dispozitive Bluetooth din apropiere"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Dispozitive din apropiere"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"descoperiți dispozitive din apropiere și conectați-vă la acestea"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Jurnale de apeluri"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"să citească și să scrie jurnalul de apeluri telefonice"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -541,10 +541,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite aplicației să descopere și să asocieze dispozitive Bluetooth din apropiere"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"să se conecteze la dispozitive Bluetooth asociate"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite aplicației să se conecteze la dispozitive Bluetooth asociate"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"să stabilească poziția relativă dintre dispozitivele Ultra-Wideband din apropiere"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permiteți-i aplicației să stabilească poziția relativă dintre dispozitivele Ultra-Wideband din apropiere"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informații despre serviciul de plăți NFC preferat"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite aplicației să obțină informații despre serviciul de plăți NFC preferat, de exemplu, identificatorii de aplicație înregistrați și destinația traseului."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlare schimb de date prin Near Field Communication"</string>
@@ -2293,9 +2295,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Acum puteți mări o parte a ecranului"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activați din Setări"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Respingeți"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"Pentru a continua, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; necesită acces la camera dispozitivului."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Activați"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Confidențialitatea privind senzorii"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Pictograma aplicației"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imaginea de branding a aplicației"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 58d10ea46a8b..d1125cfe4bd2 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -325,8 +325,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"доступ к данным о физической активности"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Камера"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"снимать фото и видео"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Устройства Bluetooth поблизости"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"находить устройства Bluetooth поблизости и подключаться к ним"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Устройства поблизости"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"находить устройства поблизости и подключаться к ним"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Список вызовов"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"чтение и запись телефонных звонков"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Телефон"</string>
@@ -544,10 +544,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Приложение сможет находить устройства Bluetooth поблизости и подключаться к ним."</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"доступ к подключенным устройствам Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"У приложения будет доступ к подключенным устройствам Bluetooth."</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"Передача рекламы на устройства Bluetooth рядом"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Приложение сможет передавать рекламу на устройства Bluetooth поблизости."</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"Определять относительное позиционирование устройств с технологией сверхширокополосной связи поблизости"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Приложение сможет определять относительное позиционирование устройств с технологией сверхширокополосной связи поблизости"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Сведения о предпочтительном платежном сервисе NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Приложение сможет получать сведения о предпочтительном платежном сервисе NFC (например, зарегистрированные идентификаторы AID и конечный пункт маршрута)."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Управление NFC-модулем"</string>
@@ -2327,9 +2327,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Теперь можно увеличивать часть экрана."</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Включить в настройках"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Закрыть"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Чтобы продолжить, предоставьте приложению &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; доступ к микрофону устройства."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Чтобы продолжить, предоставьте приложению &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; доступ к камере устройства."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Включить"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Разблокируйте микрофон устройства"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Разблокируйте камеру устройства"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Для приложения &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; и всех приложений и сервисов."</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Разблокировать"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Конфиденциальность датчиков"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Значок приложения"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Образ бренда приложения"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 541dbb867aab..d687e42f6bca 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ඔබේ ශාරීරික ක්‍රියාකාරකමට ප්‍රවේශ වන්න"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"කැමරාව"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"පින්තූර ගැනීම සහ වීඩියෝ පටිගත කිරීම"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"අවට බ්ලූටූත් උපාංග"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"අවට ඇති බ්ලූටූත් උපාංග සොයා ගන්න සහ සම්බන්ධ වන්න"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"අවට උපාංග"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"අවට උපාංග සොයා ගැනීම සහ ඒවාට සම්බන්ධ වීම"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"ඇමතුම් ලොග"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"දුරකථන ඇමතුම් ලොගය කියවන්න සහ ලියන්න"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"දුරකථනය"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"අව‍ට ඇති බ්ලූටූත් උපාංග සොයා ගැනීමට සහ යුගල කිරීමට යෙදුමට ඉඩ දෙයි"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"යුගල කළ බ්ලූටූත් උපාංගවලට සම්බන්ධ වන්න"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"යුගල කළ බ්ලූටූත් උපාංග සමඟ සම්බන්ධ වීමට යෙදුමට ඉඩ දෙයි"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"අවට ඇති බ්ලූටූත් උපාංගවලට වෙළඳ ප්‍රචාරණය කරන්න"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"අවට ඇති බ්ලූටූත් උපාංගවලට වෙළඳ ප්‍රචාරණය කිරීමට යෙදුමට ඉඩ දෙයි"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"අවට අල්ට්‍රා-වයිඩ්බෑන්ඩ් උපාංග අතර සාපේක්ෂ පිහිටීම නිර්ණය"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"අවට ඇති අල්ට්‍රා-වයිඩ්බෑන්ඩ් උපාංග අතර සාපේක්ෂ පිහිටීම නිර්ණය කිරීමට යෙදුමට ඉඩ දීම"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"කැමති NFC ගෙවීම් සේවා තොරතුරු"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ලියාපදිංචි කළ ආධාර සහ ගමන් මාර්ග ගමනාන්ත වැනි කැමති nfc ගෙවීම් සේවා තොරතුරු ලබා ගැනීමට යෙදුමට ඉඩ දෙයි."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ආසන්න ක්ෂේත්‍ර සන්නිවේදනය පාලනය කරන්න"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"ඔබට දැන් ඔබගේ තිරයේ කොටසක් විශාලනය කළ හැකිය"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"සැකසීම් තුළ ක්‍රියාත්මක කරන්න"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ඉවත ලන්න"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"දිගටම කර ගෙන යාමට, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; හට ඔබගේ උපාංගයෙහි මයික්‍රෆෝනයට ප්‍රවේශය අවශ්‍යයි."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"දිගටම කර ගෙන යාමට, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; හට ඔබගේ උපාංගයෙහි කැමරාවට ප්‍රවේශය අවශ්‍යයි."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ක්‍රියාත්මක කරන්න"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"උපාංග මයික්‍රෆෝනය අවහිර කිරීම ඉවත් කරන්න"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"උපාංග කැමරාව අවහිර කිරීම ඉවත් කරන්න"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; සහ සියලු යෙදුම් සහ සේවා සඳහා"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"අවහිර කිරීම ඉවත් කරන්න"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"සංවේදක පෞද්ගලිකත්වය"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"යෙදුම් නිරූපකය"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"යෙදුම් සන්නම් කිරීමේ රූපය"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index dd3babc9cf0d..9e12d65406e9 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -325,8 +325,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"prístup k vašej fyzickej aktivite"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Fotoaparát"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"fotenie a natáčanie videí"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Zariadenia Bluetooth nablízku"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"objaviť a pripojiť sa k zariadeniam s rozhraním Bluetooth nablízku"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Zariadenia v okolí"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"objavovať a pripájať zariadenia v okolí"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Zoznam hovorov"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"čítať a zapisovať do zoznamu hovorov"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefón"</string>
@@ -544,10 +544,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Umožňuje aplikácii objaviť zariadenia s rozhraním Bluetooth nablízku a spárovať sa s nimi"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"pripojiť sa k spárovaným zariadeniam Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Umožňuje aplikácii pripojiť sa k spárovaným zariadeniam s rozhraním Bluetooth"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"zobrazovanie reklamy v zariad. Bluetooth v okolí"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Umožňuje aplikácii zobrazovať reklamu v zariadeniach s rozhraním Bluetooth v okolí"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"určovať relatívnu polohu medzi zariadeniami so ultraširokopásmovým pripojením v okolí"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Povoľte aplikácii určovať relatívnu polohu medzi zariadeniami s ultraširokopásmovým pripojením v okolí"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferované informácie platenej služby NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Umožňuje aplikácii získavať preferované informácie platenej služby NFC, napríklad o registrovanej pomoci a trasách k cieľu."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ovládať technológiu NFC"</string>
@@ -1900,7 +1900,7 @@
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"Šetrič batérie predlžuje výdrž batérie:\n\n• zapnutím tmavého motívu;\n• vypnutím alebo obmedzením aktivity na pozadí, niektorých vizuálnych efektov a ďalších funkcií, ako napríklad kľúčového výrazu „Hey Google“.\n\n"<annotation id="url">"Ďalšie informácie"</annotation></string>
<string name="battery_saver_description" msgid="6794188153647295212">"Šetrič batérie predlžuje výdrž batérie:\n\n• zapnutím tmavého motívu;\n• vypnutím alebo obmedzením aktivity na pozadí, niektorých vizuálnych efektov a ďalších funkcií, ako napríklad kľúčového výrazu „Hey Google“."</string>
- <string name="data_saver_description" msgid="4995164271550590517">"S cieľom znížiť spotrebu dát bráni šetrič dát niektorým aplikáciám odosielať alebo prijímať dáta na pozadí. Aplikácia, ktorú práve používate, môže využívať dáta, ale možno to bude robiť menej často. Znamená to napríklad, že sa nezobrazia obrázky, kým na ne neklepnete."</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"S cieľom znížiť spotrebu dát bráni šetrič dát niektorým aplikáciám odosielať alebo prijímať dáta na pozadí. Aplikácia, ktorú práve používate, môže využívať dáta, ale možno to bude robiť menej často. Môže to napríklad znamenať, že sa obrázky zobrazia, až keď na ne klepnete."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Chcete zapnúť šetrič dát?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Zapnúť"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
@@ -2327,9 +2327,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Teraz môžete zväčšiť časť obrazovky"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Zapnúť v Nastaveniach"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Zavrieť"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Zapnúť"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Odblokujte mikrofón zariadenia"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Odblokujte fotoaparát zariadenia"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Pre aplikáciu &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; a všetky aplikácie a služby"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Odblokovať"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Ochrana súkromia senzorov"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikácie"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imidž značky aplikácie"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index ab6d10898fc5..f39e558b2aca 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -325,8 +325,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"dostop do vaše telesne dejavnosti"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Fotoaparat"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"fotografiranje in snemanje videoposnetkov"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Naprave Bluetooth v bližini"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"odkrivanje naprav Bluetooth v bližini in povezovanje z njimi"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Naprave v bližini"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"odkrivanje naprav v bližini in povezovanje z njimi"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Dnevniki klicev"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"branje in zapisovanje dnevnika klicev v telefonu"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -544,10 +544,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Aplikaciji omogoča odkrivanje naprav Bluetooth v bližini in seznanjanje z njimi."</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"povezovanje s seznanjenimi napravami Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Aplikaciji omogoča povezovanje s seznanjenimi napravami Bluetooth."</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"oglaševanje v napravah Bluetooth v bližini"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Aplikaciji dovoljuje oglaševanje v napravah Bluetooth v bližini."</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"določanje relativne oddaljenosti med napravami UWB v bližini"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Aplikaciji dovoli, da določi relativno oddaljenost med napravami UWB v bližini."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Podatki o prednostni storitvi za plačevanje prek povezave NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Aplikaciji omogoča pridobivanje podatkov o prednostni storitvi za plačevanje prek povezave NFC, kot so registrirani pripomočki in cilj preusmeritve."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"nadzor nad komunikacijo s tehnologijo bližnjega polja"</string>
@@ -1666,7 +1666,7 @@
<string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Predvajanje zaslona v napravo"</string>
<string name="media_route_chooser_searching" msgid="6119673534251329535">"Iskanje naprav …"</string>
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Nastavitve"</string>
- <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Prekinitev povezave"</string>
+ <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Prekini povezavo"</string>
<string name="media_route_status_scanning" msgid="8045156315309594482">"Pregledovanje ..."</string>
<string name="media_route_status_connecting" msgid="5845597961412010540">"Vzpostavljanje povezave ..."</string>
<string name="media_route_status_available" msgid="1477537663492007608">"Na voljo"</string>
@@ -2327,9 +2327,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Zdaj lahko povečate samo del zaslona."</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Vklopite v nastavitvah"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Opusti"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Vklopi"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Odblokiranje mikrofona v napravi"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Odblokiranje fotoaparata v napravi"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Za aplikacijo &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ter vse aplikacije in storitve"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Odblokiraj"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Zasebnost pri uporabi tipal"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikacije"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Podoba blagovne znamke aplikacije"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index c8727bbc0f9b..91d8b95c5ae4 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -319,8 +319,10 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"qasje në aktivitetin tënd fizik"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"bëj fotografi dhe regjistro video"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Pajisjet me Bluetooth në afërsi"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"të zbulojë dhe të lidhet me pajisjet me Bluetooth në afërsi"</string>
+ <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
+ <skip />
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Evidencat e telefonatave"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"lexo dhe shkruaj evidencën e telefonatave"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefoni"</string>
@@ -538,6 +540,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Lejon që aplikacioni të zbulojë dhe të çiftohet me pajisjet me Bluetooth në afërsi"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"të lidhet me pajisjet e çiftuara me Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Lejon që aplikacioni të lidhet me pajisjet e çiftuara me Bluetooth"</string>
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
+ <skip />
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
+ <skip />
<!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
<skip />
<!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
@@ -742,8 +748,8 @@
<string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"Spastroji të dhënat e këtij përdoruesi në këtë tablet pa paralajmërim."</string>
<string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"Spastroji të dhënat e këtij përdoruesi në këtë pajisje Android TV pa paralajmërim."</string>
<string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"Spastroji të dhënat e këtij përdoruesi në këtë telefon pa paralajmërim."</string>
- <string name="policylab_setGlobalProxy" msgid="215332221188670221">"Cakto përfaqësuesin global të pajisjes"</string>
- <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"Cakto përfaqësuesin global të pajisjes që të përdoret kur të aktivizohet politika. Vetëm pronari i pajisjes mund ta caktojë përfaqësuesin global."</string>
+ <string name="policylab_setGlobalProxy" msgid="215332221188670221">"Cakto proxy-in global të pajisjes"</string>
+ <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"Cakto proxy-in global të pajisjes që të përdoret kur të aktivizohet politika. Vetëm pronari i pajisjes mund ta caktojë proxy-in global."</string>
<string name="policylab_expirePassword" msgid="6015404400532459169">"Cakto skadimin e fjalëkalimit të kyçjes së ekranit"</string>
<string name="policydesc_expirePassword" msgid="9136524319325960675">"Ndrysho se sa shpesh duhet të ndërrohet fjalëkalimi, kodi PIN ose modeli i kyçjes së ekranit."</string>
<string name="policylab_encryptedStorage" msgid="9012936958126670110">"Cakto enkriptimin e hapësirës ruajtëse"</string>
@@ -1358,7 +1364,7 @@
<string name="usb_supplying_notification_title" msgid="5378546632408101811">"Pajisja e lidhur po karikohet nëpërmjet USB-së"</string>
<string name="usb_mtp_notification_title" msgid="1065989144124499810">"Transferimi i skedarëve nëpërmjet USB-së u aktivizua"</string>
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP nëpërmjet USB-së u aktivizua"</string>
- <string name="usb_tether_notification_title" msgid="8828527870612663771">"Ndarja e internetit nëpërmjet USB-së u aktivizua"</string>
+ <string name="usb_tether_notification_title" msgid="8828527870612663771">"Ndarja e internetit përmes USB-së u aktivizua"</string>
<string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI nëpërmjet USB-së u aktivizua"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"Aksesori i USB-së u lidh"</string>
<string name="usb_notification_message" msgid="4715163067192110676">"Trokit për më shumë opsione."</string>
@@ -2259,9 +2265,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Tani mund të zmadhosh pjesë të ekranit tënd"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktivizo te \"Cilësimet\""</string>
<string name="dismiss_action" msgid="1728820550388704784">"Hiq"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aktivizo"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privatësia e sensorit"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona e aplikacionit"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imazhi i vendosjes së aplikacionit të markës"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 7a15ee09b30c..1e01b7b0d9f8 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -322,8 +322,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"приступ физичким активностима"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Камера"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"снима слике и видео"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Bluetooth уређаји у близини"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"откривање и повезивање са Bluetooth уређајима у близини"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Уређаји у близини"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"откривање уређаја у близини и повезивање са њима"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Евиденције позива"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"читање и писање евиденције позива на телефону"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Телефон"</string>
@@ -541,10 +541,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Дозвољава апликацији да открива Bluetooth уређаје у близини и упарује се са њима"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"повезивање са упареним Bluetooth уређајима"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Дозвољава апликацији да се повезује са упареним Bluetooth уређајима"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"оглашавање на Bluetooth уређајима у близини"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Дозвољава апликацији да се оглашава на Bluetooth уређајима у близини"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"одређивање раздаљине између уређаја ултра-широког појаса у близини"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Дозвољава апликацији да одређује релативну раздаљину између уређаја ултра-широког појаса у близини"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информације о жељеној NFC услузи за плаћање"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дозвољава апликацији да преузима информације о жељеној NFC услузи за плаћање, попут регистрованих идентификатора апликација и одредишта преусмеравања."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"контрола комуникације у ужем пољу (Near Field Communication)"</string>
@@ -2293,9 +2293,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Сада можете да увећате део екрана"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Укључите у Подешавањима"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Одбаци"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"&lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; захтева приступ микрофону уређаја ради настављања."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; захтева приступ камери уређаја ради настављања."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Укључи"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Одблокирајте микрофон уређаја"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Одблокирајте камеру уређаја"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"За &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; и све апликације и услуге"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Одблокирај"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Приватност сензора"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Икона апликације"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Имиџ бренда апликације"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 0631772b0fe1..26bcbf7664fa 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -305,7 +305,7 @@
<string name="managed_profile_label" msgid="7316778766973512382">"Byt till jobbprofilen"</string>
<string name="permgrouplab_contacts" msgid="4254143639307316920">"Kontakter"</string>
<string name="permgroupdesc_contacts" msgid="9163927941244182567">"få tillgång till dina kontakter"</string>
- <string name="permgrouplab_location" msgid="1858277002233964394">"Plats"</string>
+ <string name="permgrouplab_location" msgid="1858277002233964394">"plats"</string>
<string name="permgroupdesc_location" msgid="1995955142118450685">"komma åt enhetens platsuppgifter"</string>
<string name="permgrouplab_calendar" msgid="6426860926123033230">"Kalender"</string>
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"få tillgång till din kalender"</string>
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"åtkomst till data om fysisk aktivitet"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ta bilder och spela in video"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Bluetooth-enheter i närheten"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"hitta och ansluta till Bluetooth-enheter i närheten"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Enheter i närheten"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"upptäcka och ansluta till enheter i närheten"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Samtalsloggar"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"läsa och skriva samtalslogg"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Tillåter appen att hitta och parkoppla Bluetooth-enheter i närheten"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ansluta till parkopplade Bluetooth-enheter"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Tillåter appen att ansluta till parkopplade Bluetooth-enheter"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"annonsera till Bluetooth-enheter i närheten"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Tillåter appen att annonsera till Bluetooth-enheter i närheten"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"fastställa relativ position för Ultra Wideband-enheter i närheten"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Tillåt att appen fastställer den relativa positionen mellan Ultra Wideband-enheter i närheten"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Information kopplad till standardtjänsten för NFC-betalning"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Tillåter att appen hämtar information kopplad till standardtjänsten för NFC-betalning, till exempel registrerade hjälpmedel och ruttdestinationer."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrollera närfältskommunikationen"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Nu kan du förstora delar av skärmen"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktivera i inställningarna"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Stäng"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"&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_notification_content" msgid="4738005643315863736">"&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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aktivera"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Återaktivera enhetens mikrofon"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Återaktivera enhetens kamera"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"För &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; och alla appar och tjänster"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Återaktivera"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorintegritet"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Appikon"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Appens varumärkesbild"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 67f64c2b8a4a..001bd3172747 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ifikie shughuli zako za kimwili"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ipige picha na kurekodi video"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Vifaa vyenye Bluetooth Vilivyo Karibu"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"kutambua na kuunganisha kwenye vifaa vyenye Bluetooth vilivyo karibu"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Vifaa vilivyo karibu"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"kutambua na kuunganisha kwenye vifaa vilivyo karibu"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Rekodi ya nambari za simu"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"kusoma na kuandika rekodi ya nambari za simu"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Simu"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Huruhusu programu itambue na kuoanisha kwenye vifaa vyenye Bluetooth vilivyo karibu"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"kuunganisha kwenye vifaa vyenye Bluetooth vilivyooanishwa"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Huruhusu programu iunganishe kwenye vifaa vyenye Bluetooth vilivyooanishwa"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"kubainisha nafasi kati ya vifaa vyenye Bendi Pana Zaidi vilivyo karibu"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Ruhusu programu ibainishe nafasi kati ya vifaa vyenye Bendi Pana Zaidi vilivyo karibu"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Maelezo ya Huduma Inayopendelewa ya Malipo ya NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Huruhusu programu kupata maelezo ya huduma inayopendelewa ya malipo ya nfc kama vile huduma zilizosajiliwa na njia."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kudhibiti Mawasiliano ya Vifaa Vilivyokaribu (NFC)"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Sasa unaweza kukuza sehemu ya skrini yako"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Washa katika Mipangilio"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Ondoa"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Washa"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Faragha ya Kitambuzi"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Aikoni ya programu"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Picha ya kuweka chapa kwenye programu"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 6e86c2008600..a1838e9d42dd 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"உடல் செயல்பாட்டைக் கண்காணிக்கும்"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"கேமரா"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"படங்கள் மற்றும் வீடியோக்கள் எடுக்கலாம்"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"அருகிலுள்ள புளூடூத் சாதனங்கள்"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"அருகிலுள்ள புளூடூத் சாதனங்களைக் கண்டறிந்து அவற்றுடன் இணையும்"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"அருகிலுள்ள சாதனங்கள்"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"அருகிலுள்ள சாதனங்களைக் கண்டறிந்து அவற்றுடன் இணையும்"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"அழைப்புப் பதிவுகள்"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"மொபைல் அழைப்புப் பதிவைப் படிக்கும், எழுதும்"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ஃபோன்"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"அருகிலுள்ள புளூடூத் சாதனங்களைக் கண்டறிந்து அவற்றுடன் இணைவதற்கு ஆப்ஸை அனுமதிக்கும்"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"இணைக்கப்பட்ட புளூடூத் சாதனங்களுடன் இணைத்தல்"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"இணைக்கப்பட்ட புளூடூத் சாதனங்களுடன் இணைவதற்கு ஆப்ஸை அனுமதிக்கும்"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"அருகிலுள்ள புளூடூத் சாதனங்களுக்கு தெரியப்படுத்தல்"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"அருகிலுள்ள புளூடூத் சாதனங்களுக்குத் தெரியப்படுத்த ஆப்ஸை அனுமதிக்கும்"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"அருகிலுள்ள அல்ட்ரா-வைடுபேண்ட் சாதனங்களுக்கிடையிலான தூரத்தைத் தீர்மானித்தல்"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"அருகிலுள்ள அல்ட்ரா-வைடுபேண்ட் சாதனங்களுக்கிடையிலான தூரத்தைத் தீர்மானிக்க ஆப்ஸை அனுமதிக்கும்"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"விருப்பமான NFC பேமெண்ட் சேவை தொடர்பான தகவல்கள்"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"பதிவுசெய்யப்பட்ட கருவிகள், சேருமிடத்திற்கான வழி போன்ற விருப்பமான NFC பேமெண்ட் சேவை தொடர்பான தகவல்களைப் பெற ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"குறுகிய இடைவெளி தகவல்பரிமாற்றத்தைக் கட்டுப்படுத்துதல்"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"இப்போது உங்கள் திரையின் ஒரு பகுதியைப் பெரிதாக்கலாம்"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"அமைப்புகளில் ஆன் செய்க"</string>
<string name="dismiss_action" msgid="1728820550388704784">"மூடுக"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"தொடர, உங்கள் சாதனத்தின் மைக்ரோஃபோனை அணுகுவதற்கு &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ஆப்ஸுக்கு அனுமதி வேண்டும்."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"தொடர, உங்கள் சாதனத்தின் கேமராவை அணுகுவதற்கு &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ஆப்ஸுக்கு அனுமதி வேண்டும்."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ஆன் செய்"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"சாதனத்தின் மைக்ரோஃபோனுக்கான தடுப்பை நீக்குதல்"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"சாதனத்தின் கேமராவுக்கான தடுப்பை நீக்குதல்"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ஆப்ஸுக்கும் அனைத்து ஆப்ஸ் மற்றும் சேவைகளுக்கும்"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"தடுப்பை நீக்கு"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"சென்சார் தனியுரிமை"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ஆப்ஸ் ஐகான்"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ஆப்ஸ் பிராண்டிங் இமேஜ்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index ea356af2e856..6e104a84385f 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -319,8 +319,10 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"భౌతిక కార్యకలాపాన్ని యాక్సెస్ చేయండి"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"కెమెరా"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"చిత్రాలను తీయడానికి మరియు వీడియోను రికార్డ్ చేయడానికి"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"సమీపంలోని బ్లూటూత్ పరికరాలు"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"సమీపంలోని బ్లూటూత్ పరికరాలను కనుగొని, కనెక్ట్ చేయండి"</string>
+ <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
+ <skip />
<string name="permgrouplab_calllog" msgid="7926834372073550288">"కాల్ లాగ్‌లు"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ఫోన్ కాల్ లాగ్‌ని చదవండి మరియు రాయండి"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ఫోన్"</string>
@@ -538,6 +540,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"సమీపంలోని బ్లూటూత్ పరికరాలను కనుగొనడానికి, పెయిర్ చేయడానికి యాప్‌ను అనుమతిస్తుంది"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"పెయిర్ చేసిన బ్లూటూత్ పరికరాలకు కనెక్ట్ అవ్వండి"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"పెయిర్ చేసిన బ్లూటూత్ పరికరాలకు కనెక్ట్ అవ్వడానికి యాప్‌ను అనుమతిస్తుంది"</string>
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
+ <skip />
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
+ <skip />
<!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
<skip />
<!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
@@ -2259,9 +2265,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"మీరు ఇప్పుడు మీ స్క్రీన్ కొంత భాగాన్ని మాగ్నిఫై చేయవచ్చు"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"సెట్టింగ్‌లలో ఆన్ చేయండి"</string>
<string name="dismiss_action" msgid="1728820550388704784">"విస్మరించు"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"కొనసాగించడానికి, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;కు మీ పరికరం యొక్క మైక్రోఫోన్ యాక్సెస్ అవసరం."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"కొనసాగించడానికి, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&amp;gtకు మీ పరికరం యొక్క కెమెరా యాక్సెస్ అవసరం."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ఆన్ చేయి"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"సెన్సార్ గోప్యత"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"యాప్ చిహ్నం"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"యాప్ బ్రాండింగ్ ఇమేజ్"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 59ea8fd52aab..f62934e23580 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"เข้าถึงกิจกรรมการเคลื่อนไหวร่างกายของคุณ"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"กล้องถ่ายรูป"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ถ่ายภาพและบันทึกวิดีโอ"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"อุปกรณ์บลูทูธที่อยู่ใกล้เคียง"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"ค้นหาและเชื่อมต่อกับอุปกรณ์บลูทูธที่อยู่ใกล้เคียง"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"อุปกรณ์ที่อยู่ใกล้เคียง"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"ค้นหาและเชื่อมต่อกับอุปกรณ์ที่อยู่ใกล้เคียง"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"ประวัติการโทร"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"อ่านและเขียนบันทึกการโทรของโทรศัพท์"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"โทรศัพท์"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"อนุญาตให้แอปค้นหาและจับคู่อุปกรณ์บลูทูธที่อยู่ใกล้เคียง"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"เชื่อมต่อกับอุปกรณ์บลูทูธที่จับคู่"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"อนุญาตให้แอปเชื่อมต่อกับอุปกรณ์บลูทูธที่จับคู่"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"ประกาศไปยังอุปกรณ์บลูทูธใกล้เคียง"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"อนุญาตให้แอปประกาศไปยังอุปกรณ์บลูทูธใกล้เคียง"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"ระบุตำแหน่งสัมพันธ์ระหว่างอุปกรณ์ที่ใช้แถบความถี่กว้างยิ่งยวดซึ่งอยู่ใกล้เคียง"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"อนุญาตให้แอประบุตำแหน่งสัมพันธ์ระหว่างอุปกรณ์ที่ใช้แถบความถี่กว้างยิ่งยวดซึ่งอยู่ใกล้เคียง"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ข้อมูลบริการชำระเงิน NFC ที่ต้องการ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"อนุญาตให้แอปรับข้อมูลบริการชำระเงิน NFC ที่ต้องการ เช่น รหัสแอป (AID) ที่ลงทะเบียนและปลายทางของเส้นทาง"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ควบคุม Near Field Communication"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"คุณขยายบางส่วนของหน้าจอได้แล้วตอนนี้"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"เปิดในการตั้งค่า"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ปิด"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"&lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ต้องได้รับสิทธิ์เข้าถึงไมโครโฟนของอุปกรณ์เพื่อดำเนินการต่อ"</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ต้องได้รับสิทธิ์เข้าถึงกล้องของอุปกรณ์เพื่อดำเนินการต่อ"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"เปิด"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"เลิกบล็อกไมโครโฟนของอุปกรณ์"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"เลิกบล็อกกล้องของอุปกรณ์"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"สำหรับ &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; รวมถึงแอปและบริการทั้งหมด"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"เลิกบล็อก"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ความเป็นส่วนตัวสำหรับเซ็นเซอร์"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ไอคอนแอปพลิเคชัน"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ภาพลักษณ์ของแบรนด์แอปพลิเคชัน"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 535e9ac280ac..8327c9160f76 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"i-access ang iyong pisikal na aktibidad"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Camera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"kumuha ng mga larawan at mag-record ng video"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Mga Malapit na Bluetooth Device"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"tumuklas at kumonekta sa mga malapit na Bluetooth device"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Mga kalapit na device"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"tumuklas ng mga kalapit na device at kumonekta sa mga ito"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Mga log ng tawag"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"binabasa at sinusulat ang log ng tawag sa telepono"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telepono"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Nagbibigay-daan sa app na tumuklas at makipagpares sa mga malapit na Bluetooth device"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"kumonekta sa mga nakapares na Bluetooth device"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Nagbibigay-daan sa app na kumonekta sa mga nakapares na Bluetooth device"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"mag-advertise sa mga kalapit na Bluetooth device"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Nagbibigay-daan sa app na mag-advertise sa mga kalapit na Bluetooth device"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"tukuyin ang relatibong posisyon sa pagitan ng mga kalapit na Ultra-Wideband device"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Payagan ang app na tukuyin ang relatibong posisyon sa pagitan ng mga kalapit na Ultra-Wideband device"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Impormasyon sa Gustong NFC na Serbisyo sa Pagbabayad"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Pinapayagan ang app na makakuha ng impormasyon sa gustong nfc na serbisyo sa pagbabayad tulad ng mga nakarehistrong application ID at destinasyon ng ruta."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolin ang Near Field Communication"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Puwede mo na ngayong i-magnify ang isang bahagi ng iyong screen"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"I-on sa Mga Setting"</string>
<string name="dismiss_action" msgid="1728820550388704784">"I-dismiss"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"I-on"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"I-unblock ang mikropono ng device"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"I-unblock ang camera ng device"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Para sa &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; at lahat ng app at serbisyo"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"I-unblock"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacy ng Sensor"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icon ng application"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Representasyon ng brand ng application"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index df4cc5eed489..8f248da776b4 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"fiziksel aktivitenize erişin"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"fotoğraf çekme ve video kaydetme"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Yakındaki Bluetooth Cihazlar"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"yakındaki Bluetooth cihazları keşfedip bağlan"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Yakındaki cihazlar"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"yakındaki cihazları keşfetme ve bağlanma"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Arama kayıtları"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"telefon arama kaydını okuma ve yazma"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Uygulamaya, yakındaki Bluetooth cihazları keşfedip eşleme izni verir"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"eşlenen Bluetooth cihazlara bağlan"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Uygulamaya, eşlenen Bluetooth cihazlara bağlanma izni verir"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"yakındaki Bluetooth cihazlara reklam yayınla"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Uygulamaya, yakındaki Bluetooth cihazlara reklam yayınlama izni verir"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"yakındaki Ultra Geniş Bant cihazların birbirine göre konumunu bul"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Uygulamanın, yakındaki Ultra Geniş Bant cihazların birbirine göre konumunu belirlemesine izin verin"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Tercih Edilen NFC Ödeme Hizmeti Bilgileri"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Uygulamaya, kayıtlı yardımlar ve rota hedefi gibi tercih edilen NFC ödeme hizmeti bilgilerini alma izni verir."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Yakın Alan İletişimini denetle"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Artık ekranınızın bir bölümünü büyütebilirsiniz"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ayarlar\'da aç"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Kapat"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aç"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Cihaz mikrofonunun engellemesini kaldır"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Cihaz kamerasının engellemesini kaldır"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ve tüm uygulamalar ile hizmetler için"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Engellemeyi kaldır"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensör Gizliliği"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Uygulama simgesi"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Uygulama marka imajı"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index ccf84d573f5b..2d0592052d5b 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -325,8 +325,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"переглядати дані про фізичну активність"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Камера"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"фотографувати та записувати відео"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Пристрої з Bluetooth поблизу"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"знаходити поблизу пристрої з Bluetooth і підключатися до них"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Пристрої поблизу"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"пошук пристроїв поблизу й підключення до них"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Журнали викликів"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"перегляд і запис журналу викликів телефона"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Телефон"</string>
@@ -544,10 +544,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Дозволяє додатку знаходити поблизу пристрої Bluetooth і створювати з ними пару"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"підключатися до пристроїв із Bluetooth, з якими є пара"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Дозволяє додатку підключатися до пристроїв із Bluetooth, з якими створено пару"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"визначення відстані між пристроями поблизу з надширокосмуговим зв’язком"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"З цим дозволом додаток може визначати відстань між розташованими поблизу пристроями з надширокосмуговим зв’язком"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Використання інформації з платіжного NFC-сервісу"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дозволяє додатку отримувати доступ до інформації потрібного платіжного NFC-сервісу (наприклад, пов\'язаних ідентифікаторів чи даних про маршрутизацію трансакцій)."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"контрол. Near Field Communication"</string>
@@ -2327,9 +2329,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Тепер можна збільшувати частину екрана"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Увімкнути в налаштуваннях"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Закрити"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Щоб продовжити, надайте додатку &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; доступ до мікрофона пристрою."</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Щоб продовжити, надайте додатку &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; доступ до камери пристрою."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Увімкнути"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Конфіденційність датчиків"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Значок додатка"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Зображення фірмової символіки додатка"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index cf3d455e0fc5..0aa550f83007 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -319,8 +319,10 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"اپنی جسمانی سرگرمی تک رسائی حاصل کریں"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"کیمرا"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"تصاویر لیں اور ویڈیو ریکارڈ کریں"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"قریبی بلوٹوتھ آلات"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"قریبی بلوٹوتھ آلات دریافت کریں اور ان سے منسلک کریں"</string>
+ <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
+ <skip />
<string name="permgrouplab_calllog" msgid="7926834372073550288">"کال لاگز"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"فون کال لاگ پڑھ کر لکھیں"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"فون"</string>
@@ -538,6 +540,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ایپ کو قریبی بلوٹوتھ آلات دریافت کرنے اور ان کا جوڑا بنانے کی اجازت دیں"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"جوڑا بنائے ہوئے بلوٹوتھ آلات سے منسلک کریں"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ایپ کو جوڑا بنائے ہوئے بلوٹوتھ آلات سے منسلک کرنے کی اجازت دیں"</string>
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
+ <skip />
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
+ <skip />
<!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
<skip />
<!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
@@ -2259,9 +2265,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"اب آپ اپنی اسکرین کے حصے کو بڑا کر سکتے ہیں"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ترتیبات میں آن کریں"</string>
<string name="dismiss_action" msgid="1728820550388704784">"برخاست کریں"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"‏جاری رکھنے کیلئے ‎<xliff:g id="APP">%s</xliff:g>&lt;b&gt;‎‏‎‎‏‏‎&lt;b&gt;‎ کو آپ کے آلے کے مائیکروفون تک رسائی درکار ہے۔"</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"‏جاری رکھنے کیلئے ‎&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;‎ کو آپ کے آلے کے کیمرے تک رسائی درکار ہے۔"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"آن کریں"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"سینسر کی رازداری"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ایپلیکیشن کا آئیکن"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ایپلیکیشن کی برانڈنگ تصویر"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index ca2ee4167269..cd5cc09924b6 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -319,8 +319,10 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"jismoniy harakatlar axborotiga ruxsat"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"suratga olish va video yozib olish"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Yaqin-atrofdagi Bluetooth qurilmalari"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"yaqin-atrofdagi Bluetooth qurilmalarini topish va ularga ulanish"</string>
+ <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
+ <skip />
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Chaqiruvlar jurnali"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"telefon chaqiruvlari jurnalini o‘qish va unga yozish"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -538,6 +540,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Ilovaga yaqin-atrofdagi Bluetooth qurilmalarini topish va juftlashish uchun ruxsat beradi"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"juftlangan Bluetooth qurilmalariga ulanish"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Ilovaga juftlangan Bluetooth qurilmalariga ulanish uchun ruxsat beradi"</string>
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"atrofdagi Bluetooth qurilmalariga reklama berish"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Ilovaga yaqin-atrofdagi Bluetooth qurilmalariga reklama yuborish imkonini beradi"</string>
<!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
<skip />
<!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
@@ -2259,9 +2263,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Ekranni qisman kattalashtirish mumkin"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Sozlamalar orqali yoqish"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Yopish"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"Davom etish uchun &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; qurilmangiz kamerasiga kirishi kerak."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Yoqish"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Qurilma mikrofonini blokdan chiqaring"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Qurilma kamerasini blokdan chiqaring"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; hamda barcha ilovalar va xizmatlar uchun"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Blokdan chiqarish"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorlar maxfiyligi"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ilova belgisi"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Ilova brendining rasmi"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index a808ce8a7250..4f5cec1e9154 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"truy cập vào hoạt động thể chất"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Máy ảnh"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"chụp ảnh và quay video"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Các thiết bị Bluetooth ở gần"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"khám phá và kết nối với các thiết bị Bluetooth ở gần"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Thiết bị ở gần"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"khám phá và kết nối với các thiết bị ở gần"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Nhật ký cuộc gọi"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"đọc và ghi nhật ký cuộc gọi điện thoại"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Điện thoại"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Cho phép ứng dụng khám phá và ghép nối với các thiết bị Bluetooth ở gần"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"kết nối với các thiết bị Bluetooth đã ghép nối"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Cho phép ứng dụng kết nối với thiết bị Bluetooth đã ghép nối"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"xác định khoảng cách tương đối giữa các thiết bị ở gần dùng Băng tần siêu rộng"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Cho phép ứng dụng xác định khoảng cách tương đối giữa các thiết bị ở gần dùng Băng tần siêu rộng"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Thông tin về dịch vụ thanh toán qua công nghệ giao tiếp tầm gần (NFC) được ưu tiên"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Cho phép ứng dụng nhận thông tin về dịch vụ thanh toán qua công nghệ giao tiếp tầm gần mà bạn ưu tiên, chẳng hạn như các hình thức hỗ trợ đã đăng ký và điểm đến trong hành trình."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kiểm soát Liên lạc trường gần"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Giờ đây, bạn có thể phóng to một phần màn hình"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Bật trong phần Cài đặt"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Đóng"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"Để 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_notification_content" msgid="4738005643315863736">"Để 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="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Bật"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Quyền riêng tư khi sử dụng cảm biến"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Biểu tượng ứng dụng"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Hình ảnh thương hiệu của ứng dụng"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 20c3fa3b84a2..a88cc8763785 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"获取您的身体活动数据"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"相机"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"拍摄照片和录制视频"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"附近的蓝牙设备"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"发现并连接到附近的蓝牙设备"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"附近的设备"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"发现并连接到附近的设备"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"通话记录"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"读取和写入手机通话记录"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"电话"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"允许该应用发现附近的蓝牙设备并与其配对"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"连接到已配对的蓝牙设备"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"允许该应用连接到已配对的蓝牙设备"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"确定附近超宽带设备之间的相对位置"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"允许应用确定附近超宽带设备之间的相对位置"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"首选 NFC 付款服务信息"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允许应用获取首选 NFC 付款服务信息,例如注册的应用标识符和路线目的地。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"控制近距离通信"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"现在您可以放大屏幕上的部分内容"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"在“设置”中开启"</string>
<string name="dismiss_action" msgid="1728820550388704784">"关闭"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"如要继续操作,请向&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;授予设备的麦克风使用权。"</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"如要继续操作,请向&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;授予设备的相机使用权。"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"开启"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"传感器隐私权"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"应用图标"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"应用品牌图片"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 5bf32cb57ec0..5066f291d2ba 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"存取體能活動"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"相機"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"拍照和錄製影片"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"附近的藍牙裝置"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"探索並連接附近的藍牙裝置"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"附近的裝置"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"探索並連接附近的裝置"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"通話記錄"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"讀取及寫入手機通話記錄"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"電話"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"允許應用程式探索並配對附近的藍牙裝置"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"連接附近的藍牙裝置"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"允許應用程式連接已配對的藍牙裝置"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"判斷附近超寬頻裝置之間的相對位置"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"允許應用程式判斷附近超寬頻裝置之間的相對位置"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"由用戶允許授權的 NFC 付款服務資訊"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允許應用程式取得由用戶允許授權的 NFC 付款服務資訊 (如已註冊的付款輔助功能和最終付款對象)。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"控制近距離無線通訊"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"您現在可以放大部分畫面"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"在「設定」中開啟"</string>
<string name="dismiss_action" msgid="1728820550388704784">"關閉"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"如要繼續,&lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; 需要裝置的麥克風存取權。"</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"如要繼續,&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; 需要裝置的相機存取權。"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"開啟"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"感應器私隱"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"應用程式圖示"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"應用程式品牌形象"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index e2c731dbe91f..5aa1046489aa 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"存取你的體能活動記錄"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"相機"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"拍照及錄製影片"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"鄰近藍牙裝置"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"探索鄰近藍牙裝置並進行連線"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"附近的裝置"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"探索附近的裝置並進行連線"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"通話記錄"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"讀取及寫入通話記錄"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"電話"</string>
@@ -538,10 +538,12 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"允許應用程式探索鄰近藍牙裝置並進行配對"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"與已配對的藍牙裝置連線"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"允許應用程式與已配對的藍牙裝置連線"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
+ <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
<skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
+ <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
<skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"判斷附近超寬頻裝置間的相對位置"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"允許應用程式判斷附近超寬頻裝置間的相對位置"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"首選 NFC 付費服務資訊"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允許應用程式取得首選 NFC 付費服務資訊,例如已註冊的輔助工具和路線目的地。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"控制近距離無線通訊"</string>
@@ -1386,7 +1388,7 @@
<string name="share_remote_bugreport_action" msgid="7630880678785123682">"分享"</string>
<string name="decline_remote_bugreport_action" msgid="4040894777519784346">"拒絕"</string>
<string name="select_input_method" msgid="3971267998568587025">"選擇輸入法"</string>
- <string name="show_ime" msgid="6406112007347443383">"連接實體鍵盤時保持顯示"</string>
+ <string name="show_ime" msgid="6406112007347443383">"使用實體鍵盤時仍繼續顯示虛擬鍵盤"</string>
<string name="hardware" msgid="1800597768237606953">"顯示虛擬鍵盤"</string>
<string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"設定實體鍵盤"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"輕觸即可選取語言和版面配置"</string>
@@ -1852,8 +1854,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"已由你的管理員更新"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"已由你的管理員刪除"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"確定"</string>
- <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"為了延長電池續航力,節約耗電量模式會執行以下動作:\n\n• 開啟深色主題\n• 關閉或限制背景活動、某些視覺效果和其他功能,例如「Ok Google」啟動字詞\n\n"<annotation id="url">"瞭解詳情"</annotation></string>
- <string name="battery_saver_description" msgid="6794188153647295212">"為了延長電池續航力,節約耗電量模式會執行以下動作:\n\n• 開啟深色主題\n• 關閉或限制背景活動、某些視覺效果和其他功能,例如「Ok Google」啟動字詞"</string>
+ <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"為了延長電池續航力,省電模式會執行以下動作:\n\n• 開啟深色主題\n• 關閉或限制背景活動、某些視覺效果和其他功能,例如「Ok Google」啟動字詞\n\n"<annotation id="url">"瞭解詳情"</annotation></string>
+ <string name="battery_saver_description" msgid="6794188153647295212">"為了延長電池續航力,省電模式會執行以下動作:\n\n• 開啟深色主題\n• 關閉或限制背景活動、某些視覺效果和其他功能,例如「Ok Google」啟動字詞"</string>
<string name="data_saver_description" msgid="4995164271550590517">"「數據節省模式」可防止部分應用程式在背景收發資料,以節省數據用量。你目前使用的應用程式可以存取資料,但存取頻率可能不如平時高。舉例來說,圖片可能不會自動顯示,在你輕觸後才會顯示。"</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"要開啟數據節省模式嗎?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"開啟"</string>
@@ -2075,7 +2077,7 @@
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"日常安排模式資訊通知"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"電池電力可能會在你平常的充電時間前耗盡"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"已啟用省電模式以延長電池續航力"</string>
- <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"節約耗電量"</string>
+ <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"省電模式"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"省電模式已關閉"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"手機電力充足,各項功能不再受到限制。"</string>
<string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"平板電腦電力充足,各項功能不再受到限制。"</string>
@@ -2259,9 +2261,14 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"你現在可以放大局部畫面了"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"在「設定」中開啟"</string>
<string name="dismiss_action" msgid="1728820550388704784">"關閉"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"如要繼續操作,請將裝置的麥克風存取權授予「<xliff:g id="APP">%s</xliff:g>」&lt;b&gt;&lt;/b&gt;。"</string>
- <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"如要繼續操作,請將裝置的相機存取權授予「<xliff:g id="APP">%s</xliff:g>」&lt;b&gt;&lt;/b&gt;。"</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"開啟"</string>
+ <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
+ <skip />
+ <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
+ <skip />
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"感應器隱私權"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"應用程式圖示"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"應用程式品牌圖片"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 4e17f8777681..9c9d4d220981 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -319,8 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"finyelela kumsebenzi wakho womzimba"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Ikhamela"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"thatha izithombe uphinde urekhode ividiyo"</string>
- <string name="permgrouplab_nearby_devices" msgid="14428105203684587">"Amadivayisi we-Bluetooth Aseduze"</string>
- <string name="permgroupdesc_nearby_devices" msgid="1146639974734121820">"thola futhi uxhume kumadivayisi we-Bluetooth aseduze"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Amadivayisi aseduze"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"thola futhi uxhume kumadivayisi aseduze"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Amarekhodi wamakholi"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"funda futhi ubhale irekhodi lamakholi efoni"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Ifoni"</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Kuvumela i-app ithole futhi ibhangqe amadivayisi we-Bluetooth aseduze"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"xhuma kumadivayisi we-Bluetooth abhangqiwe"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Kuvumela i-app ixhume kumadivayisi we-Bluetooth abhangqiwe"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"khangisa kumadivayisi e-Bluetooth aseduze"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Ivumela i-app ikhangise kumadivayisi e-Bluetooth aseduze"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"nquma indawo ehambelanayo phakathi kwamadivayisi e-Ultra-Wideband aseduze"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Vumela i-app inqume indawo ehambelanayo phakathi kwamadivayisi e-Ultra-Wideband aseduze"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Ulwazi Lwesevisi Yenkokhelo Ye-NFC Okhethwayo"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Ivuemela uhlelo lokusebenza ukuthola ulwazi lesevisi yenkokhelo ye-nfc njengezinsiza zokubhalisa nezindawo zomzila."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"lawula Uxhumano Lwenkambu Eseduze"</string>
@@ -2259,9 +2259,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Manje ungakhulisa ingxenye yesikrini sakho"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Vula Kumasethingi"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Cashisa"</string>
- <string name="sensor_privacy_start_use_mic_notification_content" msgid="8063355861118105607">"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_notification_content" msgid="4738005643315863736">"Ukuze uqhubeke, &lt;b&gt;i-<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; idinga ukufinyelela ikhamera yakho."</string>
- <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Vula"</string>
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Vulela imakrofoni yedivayisi"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Vulela ikhamera yedivayisi"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Mayelana ne-&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; nawo wonke ama-app namasevisi"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Vulela"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Ubumfihlo Benzwa"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Isithonjana sohlelo lokusebenza"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Isithombe sokubhrenda i-application"</string>
diff --git a/core/res/res/values/colors_device_defaults.xml b/core/res/res/values/colors_device_defaults.xml
index 6024cab1b729..bec0ad150b1a 100644
--- a/core/res/res/values/colors_device_defaults.xml
+++ b/core/res/res/values/colors_device_defaults.xml
@@ -48,10 +48,10 @@
<color name="accent_tertiary_variant_dark_device_default">@color/system_accent3_300</color>
<!-- Background colors -->
- <color name="background_device_default_dark">@color/system_neutral1_800</color>
+ <color name="background_device_default_dark">@color/system_neutral1_900</color>
<color name="background_device_default_light">@color/system_neutral1_50</color>
- <color name="background_floating_device_default_dark">@color/system_neutral1_900</color>
- <color name="background_floating_device_default_light">@color/system_neutral1_100</color>
+ <color name="background_floating_device_default_dark">@color/background_device_default_dark</color>
+ <color name="background_floating_device_default_light">@color/background_device_default_light</color>
<!-- Surface colors -->
<color name="surface_header_dark">@color/system_neutral1_700</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 49bd853a9c97..17ad3806e957 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -960,6 +960,13 @@
-->
<integer name="config_veryLongPressOnPowerBehavior">0</integer>
+ <!-- Control the behavior when the user presses the power and volume up buttons together.
+ 0 - Nothing
+ 1 - Mute toggle
+ 2 - Global actions menu
+ -->
+ <integer name="config_keyChordPowerVolumeUp">1</integer>
+
<!-- Control the behavior when the user long presses the back button. Non-zero values are only
valid for watches as part of CDD/CTS.
0 - Nothing
@@ -4661,10 +4668,26 @@
corners of the activity won't be rounded. -->
<integer name="config_letterboxActivityCornersRadius">0</integer>
+ <!-- Blur radius for the Option 3 in R.integer.config_letterboxBackgroundType. Values < 0 are
+ ignored and 0 is used. -->
+ <dimen name="config_letterboxBackgroundWallpaperBlurRadius">100dp</dimen>
+
+ <!-- Alpha of a black translucent scrim showed over wallpaper letterbox background when
+ the Option 3 is selected for R.integer.config_letterboxBackgroundType.
+ Values < 0 or >= 1 are ignored and 0.0 (transparent) is used instead. -->
+ <item name="config_letterboxBackgroundWallaperDarkScrimAlpha" format="float" type="dimen">
+ 0.5
+ </item>
+
<!-- Corners appearance of the letterbox background.
0 - Solid background using color specified in R.color.config_letterboxBackgroundColor.
1 - Color specified in R.attr.colorBackground for the letterboxed application.
2 - Color specified in R.attr.colorBackgroundFloating for the letterboxed application.
+ 3 - Wallpaper with dimmed with blur or/and dark scrim. At least one of the following
+ parameters should be > 0: config_letterboxBackgroundWallpaperBlurRadius,
+ config_letterboxBackgroundWallaperDarkScrimAlpha. If it's not the case or blur radius
+ provided but blur isn't supported by the device and this option
+ is selected then implementation will default to option 0.
If given value is outside of this range, the option 0 will be assummed. -->
<integer name="config_letterboxBackgroundType">0</integer>
@@ -4674,6 +4697,9 @@
R.attr.colorBackground isn't specified for the app.
- Option 2 is selected for R.integer.config_letterboxBackgroundType and
R.attr.colorBackgroundFloating isn't specified for the app.
+ - Option 3 is selected for R.integer.config_letterboxBackgroundType and blur requested
+ but isn't supported on the device or both dark scrim alpha and blur radius aren't
+ provided.
Defaults to black if not specified.
-->
<color name="config_letterboxBackgroundColor">#000</color>
@@ -4740,7 +4766,7 @@
<bool name="config_cecHdmiCecVersion20_allowed">true</bool>
<bool name="config_cecHdmiCecVersion20_default">false</bool>
- <bool name="config_cecSendStandbyOnSleep_userConfigurable">true</bool>
+ <bool name="config_cecPowerControlMode_userConfigurable">true</bool>
<bool name="config_cecPowerControlModeTv_allowed">true</bool>
<bool name="config_cecPowerControlModeTv_default">true</bool>
<bool name="config_cecPowerControlModeBroadcast_allowed">true</bool>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 9736c4b19940..3208dff1d9f6 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4983,10 +4983,10 @@
<string name="confirm_battery_saver">OK</string>
<!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, with a "learn more" link. -->
- <string name="battery_saver_description_with_learn_more">To extend battery life, Battery Saver:\n\n\u2022 Turns on Dark theme\n\u2022 Turns off or restricts background activity, some visual effects, and other features like \u201cHey Google\u201d\n\n<annotation id="url">Learn more</annotation></string>
+ <string name="battery_saver_description_with_learn_more">Battery Saver turns on Dark theme and limits or turns off background activity, some visual effects, and features like \u201cHey Google\u201d\n\n<annotation id="url">Learn more</annotation></string>
<!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, without a "learn more" link. -->
- <string name="battery_saver_description">To extend battery life, Battery Saver:\n\n\u2022 Turns on Dark theme\n\u2022 Turns off or restricts background activity, some visual effects, and other features like \u201cHey Google\u201d</string>
+ <string name="battery_saver_description">Battery Saver turns on Dark theme and limits or turns off background activity, some visual effects, and features like \u201cHey Google\u201d.</string>
<!-- [CHAR_LIMIT=NONE] Data saver: Feature description -->
<string name="data_saver_description">To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them.</string>
@@ -5513,6 +5513,21 @@
<!-- Content description of the demoted feedback icon in the notification. [CHAR LIMIT=NONE] -->
<string name="notification_feedback_indicator_demoted">This notification was ranked lower. Tap to provide feedback.</string>
+ <!-- Notification Intelligence -->
+ <!-- Title of notification indicating notification intelligence settings have changed when upgrading to S [CHAR LIMIT=30] -->
+ <string name="nas_upgrade_notification_title">Try enhanced notifications</string>
+ <!-- Content of notification indicating users need to update the settings [CHAR LIMIT=NONE] -->
+ <string name="nas_upgrade_notification_content">To keep getting suggested actions, replies, and more, turn on enhanced notifications. Android Adaptive Notifications are no longer supported.</string>
+ <!-- Label of notification action button to turn on the notification intelligence [CHAR LIMIT=20] -->
+ <string name="nas_upgrade_notification_enable_action">Turn on</string>
+ <!-- Label of notification action button to turn off the notification intelligence [CHAR LIMIT=20] -->
+ <string name="nas_upgrade_notification_disable_action">Not now</string>
+ <!-- Label of notification action button to learn more about the notification intelligence settings [CHAR LIMIT=20] -->
+ <string name="nas_upgrade_notification_learn_more_action">Learn more</string>
+ <!-- Content of notification learn more dialog about the notification intelligence settings [CHAR LIMIT=NONE] -->
+ <string name="nas_upgrade_notification_learn_more_content">Enhanced notifications can read all notification content, including personal information like contact names and messages. This feature can also dismiss notifications or take actions on buttons in notifications, such as answering phone calls.\n\nThis feature can also turn Priority mode on or off and change related settings.</string>
+
+
<!-- Dynamic mode battery saver strings -->
<!-- The user visible name of the notification channel for the routine mode battery saver fyi notification [CHAR_LIMIT=80]-->
<string name="dynamic_mode_notification_channel_name">Routine Mode info notification</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3f37575736b8..4bb323661d33 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -435,6 +435,7 @@
<java-symbol type="integer" name="config_veryLongPressTimeout" />
<java-symbol type="integer" name="config_longPressOnBackBehavior" />
<java-symbol type="bool" name="config_allowStartActivityForLongPressOnPowerInSetup" />
+ <java-symbol type="integer" name="config_keyChordPowerVolumeUp" />
<java-symbol type="integer" name="config_wakeUpToLastStateTimeoutMillis" />
<java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAdjust" />
<java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAbsolute" />
@@ -2263,6 +2264,12 @@
<java-symbol type="style" name="Animation.RecentApplications" />
<java-symbol type="integer" name="dock_enter_exit_duration" />
<java-symbol type="bool" name="config_battery_percentage_setting_available" />
+ <java-symbol type="string" name="nas_upgrade_notification_title" />
+ <java-symbol type="string" name="nas_upgrade_notification_content" />
+ <java-symbol type="string" name="nas_upgrade_notification_enable_action" />
+ <java-symbol type="string" name="nas_upgrade_notification_disable_action" />
+ <java-symbol type="string" name="nas_upgrade_notification_learn_more_action" />
+ <java-symbol type="string" name="nas_upgrade_notification_learn_more_content" />
<!-- ImfTest -->
<java-symbol type="layout" name="auto_complete_list" />
@@ -4170,7 +4177,9 @@
<java-symbol type="dimen" name="controls_thumbnail_image_max_width" />
<java-symbol type="dimen" name="config_fixedOrientationLetterboxAspectRatio" />
+ <java-symbol type="dimen" name="config_letterboxBackgroundWallpaperBlurRadius" />
<java-symbol type="integer" name="config_letterboxActivityCornersRadius" />
+ <java-symbol type="dimen" name="config_letterboxBackgroundWallaperDarkScrimAlpha" />
<java-symbol type="integer" name="config_letterboxBackgroundType" />
<java-symbol type="color" name="config_letterboxBackgroundColor" />
@@ -4238,7 +4247,7 @@
<java-symbol type="bool" name="config_cecHdmiCecVersion20_allowed" />
<java-symbol type="bool" name="config_cecHdmiCecVersion20_default" />
- <java-symbol type="bool" name="config_cecSendStandbyOnSleep_userConfigurable" />
+ <java-symbol type="bool" name="config_cecPowerControlMode_userConfigurable" />
<java-symbol type="bool" name="config_cecPowerControlModeTv_allowed" />
<java-symbol type="bool" name="config_cecPowerControlModeTv_default" />
<java-symbol type="bool" name="config_cecPowerControlModeBroadcast_allowed" />
diff --git a/core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/ConnectivitySetupRule.java b/core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/ConnectivitySetupRule.java
index 1afc22b7406d..14d740d2e8c4 100644
--- a/core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/ConnectivitySetupRule.java
+++ b/core/tests/batterystatstests/BatteryStatsLoadTests/src/com/android/frameworks/core/batterystatsloadtests/ConnectivitySetupRule.java
@@ -21,7 +21,6 @@ import static org.junit.Assert.assertEquals;
import android.app.Instrumentation;
import android.content.Context;
import android.net.ConnectivityManager;
-import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
@@ -128,8 +127,7 @@ public class ConnectivitySetupRule implements TestRule {
}
@Override
- public void onAvailable(Network network, NetworkCapabilities networkCapabilities,
- LinkProperties linkProperties, boolean blocked) {
+ public void onAvailable(Network network) {
checkActiveNetwork();
}
diff --git a/core/tests/coretests/src/android/app/admin/OWNERS b/core/tests/coretests/src/android/app/admin/OWNERS
new file mode 100644
index 000000000000..e95633abe79a
--- /dev/null
+++ b/core/tests/coretests/src/android/app/admin/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/app/admin/OWNERS
diff --git a/core/tests/coretests/src/android/app/servertransaction/TestUtils.java b/core/tests/coretests/src/android/app/servertransaction/TestUtils.java
index 1a06789e729f..75da0bfba581 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TestUtils.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TestUtils.java
@@ -111,6 +111,7 @@ class TestUtils {
private IBinder mAssistToken;
private IBinder mShareableActivityToken;
private FixedRotationAdjustments mFixedRotationAdjustments;
+ private boolean mLaunchedFromBubble;
LaunchActivityItemBuilder setIntent(Intent intent) {
mIntent = intent;
@@ -207,13 +208,18 @@ class TestUtils {
return this;
}
+ LaunchActivityItemBuilder setLaunchedFromBubble(boolean launchedFromBubble) {
+ mLaunchedFromBubble = launchedFromBubble;
+ return this;
+ }
+
LaunchActivityItem build() {
return LaunchActivityItem.obtain(mIntent, mIdent, mInfo,
mCurConfig, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor,
mProcState, mState, mPersistentState, mPendingResults, mPendingNewIntents,
mActivityOptions, mIsForward, mProfilerInfo, mAssistToken,
null /* activityClientController */, mFixedRotationAdjustments,
- mShareableActivityToken);
+ mShareableActivityToken, mLaunchedFromBubble);
}
}
}
diff --git a/core/tests/coretests/src/android/app/time/ExternalTimeSuggestionTest.java b/core/tests/coretests/src/android/app/time/ExternalTimeSuggestionTest.java
deleted file mode 100644
index 1c6b3cc47a45..000000000000
--- a/core/tests/coretests/src/android/app/time/ExternalTimeSuggestionTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 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.time;
-
-import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
-import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-
-import android.os.TimestampedValue;
-
-import org.junit.Test;
-
-public class ExternalTimeSuggestionTest {
-
- private static final TimestampedValue<Long> ARBITRARY_TIME =
- new TimestampedValue<>(1111L, 2222L);
-
- @Test
- public void testEquals() {
- ExternalTimeSuggestion one = new ExternalTimeSuggestion(
- ARBITRARY_TIME.getReferenceTimeMillis(),
- ARBITRARY_TIME.getValue());
- assertEquals(one, one);
-
- ExternalTimeSuggestion two = new ExternalTimeSuggestion(
- ARBITRARY_TIME.getReferenceTimeMillis(),
- ARBITRARY_TIME.getValue());
- assertEquals(one, two);
- assertEquals(two, one);
-
- ExternalTimeSuggestion three = new ExternalTimeSuggestion(
- ARBITRARY_TIME.getReferenceTimeMillis() + 1,
- ARBITRARY_TIME.getValue());
- assertNotEquals(one, three);
- assertNotEquals(three, one);
-
- // DebugInfo must not be considered in equals().
- one.addDebugInfo("Debug info 1");
- two.addDebugInfo("Debug info 2");
- assertEquals(one, two);
- }
-
- @Test
- public void testParcelable() {
- ExternalTimeSuggestion suggestion = new ExternalTimeSuggestion(
- ARBITRARY_TIME.getReferenceTimeMillis(),
- ARBITRARY_TIME.getValue());
- assertRoundTripParcelable(suggestion);
-
- // DebugInfo should also be stored (but is not checked by equals())
- suggestion.addDebugInfo("This is debug info");
- ExternalTimeSuggestion rtSuggestion = roundTripParcelable(suggestion);
- assertEquals(suggestion.getDebugInfo(), rtSuggestion.getDebugInfo());
- }
-}
diff --git a/core/tests/coretests/src/android/content/ContentProviderTest.java b/core/tests/coretests/src/android/content/ContentProviderTest.java
index b28206402137..ceebc621f51f 100644
--- a/core/tests/coretests/src/android/content/ContentProviderTest.java
+++ b/core/tests/coretests/src/android/content/ContentProviderTest.java
@@ -89,9 +89,9 @@ public class ContentProviderTest {
}
@Test
- public void testCreateContentUriAsUser() {
+ public void testCreateContentUriForUser() {
Uri uri = Uri.parse("content://com.example/foo/bar");
Uri expectedUri = Uri.parse("content://7@com.example/foo/bar");
- assertEquals(expectedUri, ContentProvider.createContentUriAsUser(uri, UserHandle.of(7)));
+ assertEquals(expectedUri, ContentProvider.createContentUriForUser(uri, UserHandle.of(7)));
}
}
diff --git a/core/tests/coretests/src/android/net/SntpClientTest.java b/core/tests/coretests/src/android/net/SntpClientTest.java
index 87edb6e01425..bf9978c2c447 100644
--- a/core/tests/coretests/src/android/net/SntpClientTest.java
+++ b/core/tests/coretests/src/android/net/SntpClientTest.java
@@ -20,6 +20,9 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
+import static org.mockito.Mockito.mock;
+
import android.util.Log;
import androidx.test.runner.AndroidJUnit4;
@@ -73,8 +76,9 @@ public class SntpClientTest {
@Before
public void setUp() throws Exception {
- // NETID_UNSET allows the test to run, with a loopback server, even w/o external networking
- mNetwork = new Network(ConnectivityManager.NETID_UNSET);
+ // A mock network has NETID_UNSET, which allows the test to run, with a loopback server,
+ // even w/o external networking.
+ mNetwork = mock(Network.class, CALLS_REAL_METHODS);
mServer = new SntpTestServer();
mClient = new SntpClient();
}
diff --git a/core/tests/coretests/src/android/os/CombinedVibrationEffectTest.java b/core/tests/coretests/src/android/os/CombinedVibrationTest.java
index 30b2d8e47ab1..06b5d180518f 100644
--- a/core/tests/coretests/src/android/os/CombinedVibrationEffectTest.java
+++ b/core/tests/coretests/src/android/os/CombinedVibrationTest.java
@@ -33,75 +33,75 @@ import java.util.Arrays;
@Presubmit
@RunWith(JUnit4.class)
-public class CombinedVibrationEffectTest {
+public class CombinedVibrationTest {
private static final VibrationEffect VALID_EFFECT = VibrationEffect.createOneShot(10, 255);
private static final VibrationEffect INVALID_EFFECT = new VibrationEffect.Composed(
new ArrayList<>(), 0);
@Test
public void testValidateMono() {
- CombinedVibrationEffect.createSynced(VALID_EFFECT);
+ CombinedVibration.createParallel(VALID_EFFECT);
assertThrows(IllegalArgumentException.class,
- () -> CombinedVibrationEffect.createSynced(INVALID_EFFECT));
+ () -> CombinedVibration.createParallel(INVALID_EFFECT));
}
@Test
public void testValidateStereo() {
- CombinedVibrationEffect.startSynced()
+ CombinedVibration.startParallel()
.addVibrator(0, VALID_EFFECT)
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
.combine();
- CombinedVibrationEffect.startSynced()
+ CombinedVibration.startParallel()
.addVibrator(0, INVALID_EFFECT)
.addVibrator(0, VALID_EFFECT)
.combine();
assertThrows(IllegalArgumentException.class,
- () -> CombinedVibrationEffect.startSynced()
+ () -> CombinedVibration.startParallel()
.addVibrator(0, INVALID_EFFECT)
.combine());
}
@Test
public void testValidateSequential() {
- CombinedVibrationEffect.startSequential()
+ CombinedVibration.startSequential()
.addNext(0, VALID_EFFECT)
- .addNext(CombinedVibrationEffect.createSynced(VALID_EFFECT))
+ .addNext(CombinedVibration.createParallel(VALID_EFFECT))
.combine();
- CombinedVibrationEffect.startSequential()
+ CombinedVibration.startSequential()
.addNext(0, VALID_EFFECT)
.addNext(0, VALID_EFFECT, 100)
.combine();
- CombinedVibrationEffect.startSequential()
- .addNext(CombinedVibrationEffect.startSequential()
+ CombinedVibration.startSequential()
+ .addNext(CombinedVibration.startSequential()
.addNext(0, VALID_EFFECT)
.combine())
.combine();
assertThrows(IllegalArgumentException.class,
- () -> CombinedVibrationEffect.startSequential()
+ () -> CombinedVibration.startSequential()
.addNext(0, VALID_EFFECT, -1)
.combine());
assertThrows(IllegalArgumentException.class,
- () -> CombinedVibrationEffect.startSequential()
+ () -> CombinedVibration.startSequential()
.addNext(0, INVALID_EFFECT)
.combine());
}
@Test
public void testNestedSequentialAccumulatesDelays() {
- CombinedVibrationEffect.Sequential combined =
- (CombinedVibrationEffect.Sequential) CombinedVibrationEffect.startSequential()
- .addNext(CombinedVibrationEffect.startSequential()
+ CombinedVibration.Sequential combined =
+ (CombinedVibration.Sequential) CombinedVibration.startSequential()
+ .addNext(CombinedVibration.startSequential()
.addNext(0, VALID_EFFECT, /* delay= */ 100)
.addNext(1, VALID_EFFECT, /* delay= */ 100)
.combine(),
/* delay= */ 10)
- .addNext(CombinedVibrationEffect.startSequential()
+ .addNext(CombinedVibration.startSequential()
.addNext(0, VALID_EFFECT, /* delay= */ 100)
.combine())
- .addNext(CombinedVibrationEffect.startSequential()
+ .addNext(CombinedVibration.startSequential()
.addNext(0, VALID_EFFECT)
.addNext(0, VALID_EFFECT, /* delay= */ 100)
.combine(),
@@ -114,37 +114,37 @@ public class CombinedVibrationEffectTest {
@Test
public void testCombineEmptyFails() {
assertThrows(IllegalStateException.class,
- () -> CombinedVibrationEffect.startSynced().combine());
+ () -> CombinedVibration.startParallel().combine());
assertThrows(IllegalStateException.class,
- () -> CombinedVibrationEffect.startSequential().combine());
+ () -> CombinedVibration.startSequential().combine());
}
@Test
public void testDurationMono() {
- assertEquals(1, CombinedVibrationEffect.createSynced(
+ assertEquals(1, CombinedVibration.createParallel(
VibrationEffect.createOneShot(1, 1)).getDuration());
- assertEquals(-1, CombinedVibrationEffect.createSynced(
+ assertEquals(-1, CombinedVibration.createParallel(
VibrationEffect.get(VibrationEffect.EFFECT_CLICK)).getDuration());
- assertEquals(Long.MAX_VALUE, CombinedVibrationEffect.createSynced(
+ assertEquals(Long.MAX_VALUE, CombinedVibration.createParallel(
VibrationEffect.createWaveform(
new long[]{1, 2, 3}, new int[]{1, 2, 3}, 0)).getDuration());
}
@Test
public void testDurationStereo() {
- assertEquals(6, CombinedVibrationEffect.startSynced()
+ assertEquals(6, CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.createOneShot(1, 1))
.addVibrator(2,
VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, -1))
.combine()
.getDuration());
- assertEquals(-1, CombinedVibrationEffect.startSynced()
+ assertEquals(-1, CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.addVibrator(2,
VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, -1))
.combine()
.getDuration());
- assertEquals(Long.MAX_VALUE, CombinedVibrationEffect.startSynced()
+ assertEquals(Long.MAX_VALUE, CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.addVibrator(2,
VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, 0))
@@ -154,19 +154,19 @@ public class CombinedVibrationEffectTest {
@Test
public void testDurationSequential() {
- assertEquals(26, CombinedVibrationEffect.startSequential()
+ assertEquals(26, CombinedVibration.startSequential()
.addNext(1, VibrationEffect.createOneShot(10, 10), 10)
.addNext(2,
VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, -1))
.combine()
.getDuration());
- assertEquals(-1, CombinedVibrationEffect.startSequential()
+ assertEquals(-1, CombinedVibration.startSequential()
.addNext(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.addNext(2,
VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, -1))
.combine()
.getDuration());
- assertEquals(Long.MAX_VALUE, CombinedVibrationEffect.startSequential()
+ assertEquals(Long.MAX_VALUE, CombinedVibration.startSequential()
.addNext(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.addNext(2,
VibrationEffect.createWaveform(new long[]{1, 2, 3}, new int[]{1, 2, 3}, 0))
@@ -176,7 +176,7 @@ public class CombinedVibrationEffectTest {
@Test
public void testHasVibratorMono_returnsTrueForAnyVibrator() {
- CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
+ CombinedVibration effect = CombinedVibration.createParallel(
VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
assertTrue(effect.hasVibrator(0));
assertTrue(effect.hasVibrator(1));
@@ -184,7 +184,7 @@ public class CombinedVibrationEffectTest {
@Test
public void testHasVibratorStereo_returnsOnlyTheIdsSet() {
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+ CombinedVibration effect = CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.combine();
assertFalse(effect.hasVibrator(0));
@@ -194,9 +194,9 @@ public class CombinedVibrationEffectTest {
@Test
public void testHasVibratorSequential_returnsNestedVibrators() {
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSequential()
+ CombinedVibration effect = CombinedVibration.startSequential()
.addNext(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
- .addNext(CombinedVibrationEffect.startSynced()
+ .addNext(CombinedVibration.startParallel()
.addVibrator(2, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
.combine())
.combine();
@@ -207,18 +207,18 @@ public class CombinedVibrationEffectTest {
@Test
public void testSerializationMono() {
- CombinedVibrationEffect original = CombinedVibrationEffect.createSynced(VALID_EFFECT);
+ CombinedVibration original = CombinedVibration.createParallel(VALID_EFFECT);
Parcel parcel = Parcel.obtain();
original.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
- CombinedVibrationEffect restored = CombinedVibrationEffect.CREATOR.createFromParcel(parcel);
+ CombinedVibration restored = CombinedVibration.CREATOR.createFromParcel(parcel);
assertEquals(original, restored);
}
@Test
public void testSerializationStereo() {
- CombinedVibrationEffect original = CombinedVibrationEffect.startSynced()
+ CombinedVibration original = CombinedVibration.startParallel()
.addVibrator(0, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.addVibrator(1, VibrationEffect.createOneShot(10, 255))
.combine();
@@ -226,22 +226,22 @@ public class CombinedVibrationEffectTest {
Parcel parcel = Parcel.obtain();
original.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
- CombinedVibrationEffect restored = CombinedVibrationEffect.CREATOR.createFromParcel(parcel);
+ CombinedVibration restored = CombinedVibration.CREATOR.createFromParcel(parcel);
assertEquals(original, restored);
}
@Test
public void testSerializationSequential() {
- CombinedVibrationEffect original = CombinedVibrationEffect.startSequential()
+ CombinedVibration original = CombinedVibration.startSequential()
.addNext(0, VALID_EFFECT)
- .addNext(CombinedVibrationEffect.createSynced(VALID_EFFECT))
+ .addNext(CombinedVibration.createParallel(VALID_EFFECT))
.addNext(0, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), 100)
.combine();
Parcel parcel = Parcel.obtain();
original.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
- CombinedVibrationEffect restored = CombinedVibrationEffect.CREATOR.createFromParcel(parcel);
+ CombinedVibration restored = CombinedVibration.CREATOR.createFromParcel(parcel);
assertEquals(original, restored);
}
}
diff --git a/core/tests/coretests/src/android/os/FileUtilsTest.java b/core/tests/coretests/src/android/os/FileUtilsTest.java
index 1a86678a30b4..c1e72fe75666 100644
--- a/core/tests/coretests/src/android/os/FileUtilsTest.java
+++ b/core/tests/coretests/src/android/os/FileUtilsTest.java
@@ -228,6 +228,27 @@ public class FileUtilsTest {
}
@Test
+ public void testCopyFileWithAppend() throws Exception {
+ final File src = new File(mTarget, "src");
+ final File dest = new File(mTarget, "dest");
+
+ byte[] expected = new byte[10];
+ byte[] actual = new byte[10];
+ new Random().nextBytes(expected);
+ writeFile(src, expected);
+
+ try (FileInputStream in = new FileInputStream(src);
+ FileOutputStream out = new FileOutputStream(dest, true /* append */)) {
+ // sendfile(2) fails if output fd is opened with O_APPEND, but FileUtils#copy should
+ // fallback to userspace copy
+ FileUtils.copy(in, out);
+ }
+
+ actual = readFile(dest);
+ assertArrayEquals(expected, actual);
+ }
+
+ @Test
public void testIsFilenameSafe() throws Exception {
assertTrue(FileUtils.isFilenameSafe(new File("foobar")));
assertTrue(FileUtils.isFilenameSafe(new File("a_b-c=d.e/0,1+23")));
@@ -577,7 +598,6 @@ public class FileUtilsTest {
final File validVideoCameraDir = new File(cameraDir, "validVideo-" + nonce + ".mp4");
final File validImageCameraDir = new File(cameraDir, "validImage-" + nonce + ".jpg");
- final File invalidVideoCameraDir = new File(cameraDir, ".invalidVideo-" + nonce + ".mp4");
final File validVideoNonCameraDir = new File(nonCameraDir, "validVideo-" + nonce + ".mp4");
final File validImageNonCameraDir = new File(nonCameraDir, "validImage-" + nonce + ".jpg");
@@ -589,9 +609,6 @@ public class FileUtilsTest {
FileDescriptor pfdValidImageCameraDir =
ParcelFileDescriptor.open(validImageCameraDir,
MODE_CREATE | MODE_READ_WRITE).getFileDescriptor();
- FileDescriptor pfdInvalidVideoCameraDir =
- ParcelFileDescriptor.open(invalidVideoCameraDir,
- MODE_CREATE | MODE_READ_WRITE).getFileDescriptor();
FileDescriptor pfdValidVideoNonCameraDir =
ParcelFileDescriptor.open(validVideoNonCameraDir,
@@ -603,13 +620,11 @@ public class FileUtilsTest {
assertNotNull(convertToModernFd(pfdValidVideoCameraDir));
assertNull(convertToModernFd(pfdValidImageCameraDir));
- assertNull(convertToModernFd(pfdInvalidVideoCameraDir));
assertNull(convertToModernFd(pfdValidVideoNonCameraDir));
assertNull(convertToModernFd(pfdValidImageNonCameraDir));
} finally {
validVideoCameraDir.delete();
validImageCameraDir.delete();
- invalidVideoCameraDir.delete();
validVideoNonCameraDir.delete();
validImageNonCameraDir.delete();
}
diff --git a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java
new file mode 100644
index 000000000000..7dea82d7ee54
--- /dev/null
+++ b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java
@@ -0,0 +1,211 @@
+/*
+ * 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.os;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNotNull;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.os.PerformanceHintManager.Session;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class PerformanceHintManagerTest {
+ private static final long RATE_1000 = 1000L;
+ private static final long TARGET_166 = 166L;
+ private static final long DEFAULT_TARGET_NS = 16666666L;
+ private PerformanceHintManager mPerformanceHintManager;
+
+ @Mock
+ private IHintSession mIHintSessionMock;
+
+ @Before
+ public void setUp() {
+ mPerformanceHintManager =
+ InstrumentationRegistry.getInstrumentation().getContext().getSystemService(
+ PerformanceHintManager.class);
+ MockitoAnnotations.initMocks(this);
+ }
+
+ private Session createSession() {
+ return mPerformanceHintManager.createHintSession(
+ new int[]{Process.myPid()}, DEFAULT_TARGET_NS);
+ }
+
+ @Test
+ public void testCreateHintSession() {
+ Session a = createSession();
+ Session b = createSession();
+ if (a == null) {
+ assertNull(b);
+ } else {
+ assertNotEquals(a, b);
+ }
+ }
+
+ @Test
+ public void testGetPreferredUpdateRateNanos() {
+ if (createSession() != null) {
+ assertTrue(mPerformanceHintManager.getPreferredUpdateRateNanos() > 0);
+ } else {
+ assertEquals(-1, mPerformanceHintManager.getPreferredUpdateRateNanos());
+ }
+ }
+
+ @Test
+ public void testUpdateTargetWorkDuration() {
+ Session s = createSession();
+ assumeNotNull(s);
+ s.updateTargetWorkDuration(100);
+ }
+
+ @Test
+ public void testUpdateTargetWorkDurationWithNegativeDuration() {
+ Session s = createSession();
+ assumeNotNull(s);
+ assertThrows(IllegalArgumentException.class, () -> {
+ s.updateTargetWorkDuration(-1);
+ });
+ }
+
+ @Test
+ public void testReportActualWorkDuration() {
+ Session s = createSession();
+ assumeNotNull(s);
+ s.updateTargetWorkDuration(100);
+ s.reportActualWorkDuration(1);
+ s.reportActualWorkDuration(100);
+ s.reportActualWorkDuration(1000);
+ }
+
+ @Test
+ public void testReportActualWorkDurationWithIllegalArgument() {
+ Session s = createSession();
+ assumeNotNull(s);
+ s.updateTargetWorkDuration(100);
+ assertThrows(IllegalArgumentException.class, () -> {
+ s.reportActualWorkDuration(-1);
+ });
+ }
+
+ @Test
+ public void testRateLimitWithDurationFastEnough() throws Exception {
+ FakeClock fakeClock = new FakeClock();
+ Session s = new Session(mIHintSessionMock, fakeClock, RATE_1000, TARGET_166);
+
+ reset(mIHintSessionMock);
+ fakeClock.setNow(0);
+ s.updateTargetWorkDuration(TARGET_166);
+
+ s.reportActualWorkDuration(TARGET_166 - 1);
+ s.reportActualWorkDuration(TARGET_166);
+ // we should not see update as the rate should be 10X for over-perform case.
+ verify(mIHintSessionMock, never()).reportActualWorkDuration(any(), any());
+ fakeClock.incrementClock(10 * RATE_1000);
+ s.reportActualWorkDuration(TARGET_166);
+ verify(mIHintSessionMock, never()).reportActualWorkDuration(any(), any());
+ fakeClock.incrementClock(1);
+ s.reportActualWorkDuration(TARGET_166);
+ // we should see update after rate limit
+ verify(mIHintSessionMock, times(1)).reportActualWorkDuration(
+ eq(new long[] {TARGET_166 - 1, TARGET_166, TARGET_166, TARGET_166}),
+ eq(new long[] {0, 0, 10 * RATE_1000, 10 * RATE_1000 + 1}));
+
+ reset(mIHintSessionMock);
+ s.reportActualWorkDuration(TARGET_166);
+ s.reportActualWorkDuration(TARGET_166 - 1);
+ s.reportActualWorkDuration(TARGET_166 - 2);
+ // we should not see update as the rate should be 10X for over-perform case.
+ verify(mIHintSessionMock, never()).reportActualWorkDuration(any(), any());
+ fakeClock.incrementClock(10 * RATE_1000 + 1);
+ s.reportActualWorkDuration(TARGET_166);
+ s.reportActualWorkDuration(TARGET_166 - 1);
+ // we should see update now
+ verify(mIHintSessionMock, times(1)).reportActualWorkDuration(
+ eq(new long[] {TARGET_166, TARGET_166 - 1, TARGET_166 - 2, TARGET_166}),
+ eq(new long[] {10 * RATE_1000 + 1, 10 * RATE_1000 + 1, 10 * RATE_1000 + 1,
+ (10 * RATE_1000 + 1) * 2}));
+ }
+
+ @Test
+ public void testRateLimitWithDurationTooSlow() throws Exception {
+ FakeClock fakeClock = new FakeClock();
+ Session s = new Session(mIHintSessionMock, fakeClock, RATE_1000, TARGET_166);
+
+ reset(mIHintSessionMock);
+ fakeClock.setNow(0);
+ s.updateTargetWorkDuration(TARGET_166);
+
+ verify(mIHintSessionMock, times(1)).updateTargetWorkDuration(eq(TARGET_166));
+ // shouldn't update before rate limit
+ s.reportActualWorkDuration(TARGET_166 + 1);
+ verify(mIHintSessionMock, never()).reportActualWorkDuration(any(), any());
+
+ // shouldn't update when the time is exactly at rate limit
+ fakeClock.incrementClock(RATE_1000);
+ s.reportActualWorkDuration(TARGET_166 + 1);
+ verify(mIHintSessionMock, never()).reportActualWorkDuration(any(), any());
+
+ // should be ready for sending hint
+ fakeClock.incrementClock(1);
+ s.reportActualWorkDuration(TARGET_166 + 1);
+ verify(mIHintSessionMock, times(1)).reportActualWorkDuration(
+ eq(new long[] {TARGET_166 + 1, TARGET_166 + 1, TARGET_166 + 1}),
+ eq(new long[] {0 , RATE_1000, RATE_1000 + 1}));
+ }
+
+ @Test
+ public void testCloseHintSession() {
+ Session s = createSession();
+ assumeNotNull(s);
+ s.close();
+ }
+
+ private static class FakeClock implements PerformanceHintManager.NanoClock {
+ private long mCurrentTime = 0L;
+
+ @Override
+ public long nanos() {
+ return mCurrentTime;
+ }
+
+ public void setNow(long nanos) {
+ mCurrentTime = nanos;
+ }
+
+ public void incrementClock(long nanos) {
+ mCurrentTime += nanos;
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/service/timezone/ParcelableTestSupport.java b/core/tests/coretests/src/android/service/timezone/ParcelableTestSupport.java
deleted file mode 100644
index 777bda9fe1ff..000000000000
--- a/core/tests/coretests/src/android/service/timezone/ParcelableTestSupport.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.timezone;
-
-import static org.junit.Assert.assertEquals;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.reflect.Field;
-
-/** Utility methods related to {@link Parcelable} objects used in several tests. */
-final class ParcelableTestSupport {
-
- private ParcelableTestSupport() {}
-
- /** Returns the result of parceling and unparceling the argument. */
- @SuppressWarnings("unchecked")
- public static <T extends Parcelable> T roundTripParcelable(T parcelable) {
- Parcel parcel = Parcel.obtain();
- parcel.writeTypedObject(parcelable, 0);
- parcel.setDataPosition(0);
-
- Parcelable.Creator<T> creator;
- try {
- Field creatorField = parcelable.getClass().getField("CREATOR");
- creator = (Parcelable.Creator<T>) creatorField.get(null);
- } catch (NoSuchFieldException | IllegalAccessException e) {
- throw new AssertionError(e);
- }
- T toReturn = parcel.readTypedObject(creator);
- parcel.recycle();
- return toReturn;
- }
-
- public static <T extends Parcelable> void assertRoundTripParcelable(T instance) {
- assertEquals(instance, roundTripParcelable(instance));
- }
-}
diff --git a/core/tests/coretests/src/android/service/timezone/TimeZoneProviderSuggestionTest.java b/core/tests/coretests/src/android/service/timezone/TimeZoneProviderSuggestionTest.java
deleted file mode 100644
index f805555145f6..000000000000
--- a/core/tests/coretests/src/android/service/timezone/TimeZoneProviderSuggestionTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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.service.timezone;
-
-import static android.service.timezone.ParcelableTestSupport.assertRoundTripParcelable;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-
-import static java.util.Collections.singletonList;
-
-import org.junit.Test;
-
-import java.util.List;
-
-public class TimeZoneProviderSuggestionTest {
-
- private static final long ARBITRARY_ELAPSED_REALTIME_MILLIS = 9999;
-
- private static final List<String> ARBITRARY_TIME_ZONE_IDS = singletonList("Europe/London");
-
- @Test(expected = RuntimeException.class)
- public void testInvalidTimeZoneIds() {
- new TimeZoneProviderSuggestion.Builder()
- .setTimeZoneIds(null);
- }
-
- @Test
- public void testEquals() {
- TimeZoneProviderSuggestion.Builder builder1 = new TimeZoneProviderSuggestion.Builder()
- .setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS);
- {
- TimeZoneProviderSuggestion one = builder1.build();
- assertEquals(one, one);
- }
-
- TimeZoneProviderSuggestion.Builder builder2 = new TimeZoneProviderSuggestion.Builder()
- .setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS);
- {
- TimeZoneProviderSuggestion one = builder1.build();
- TimeZoneProviderSuggestion two = builder2.build();
- assertEquals(one, two);
- assertEquals(two, one);
- }
-
- builder1.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS + 1);
- {
- TimeZoneProviderSuggestion one = builder1.build();
- TimeZoneProviderSuggestion two = builder2.build();
- assertNotEquals(one, two);
- assertNotEquals(two, one);
- }
-
- builder2.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS + 1);
- {
- TimeZoneProviderSuggestion one = builder1.build();
- TimeZoneProviderSuggestion two = builder2.build();
- assertEquals(one, two);
- assertEquals(two, one);
- }
-
- builder2.setTimeZoneIds(ARBITRARY_TIME_ZONE_IDS);
- {
- TimeZoneProviderSuggestion one = builder1.build();
- TimeZoneProviderSuggestion two = builder2.build();
- assertNotEquals(one, two);
- assertNotEquals(two, one);
- }
-
- builder1.setTimeZoneIds(ARBITRARY_TIME_ZONE_IDS);
- {
- TimeZoneProviderSuggestion one = builder1.build();
- TimeZoneProviderSuggestion two = builder2.build();
- assertEquals(one, two);
- assertEquals(two, one);
- }
- }
-
- @Test
- public void testParcelable_noTimeZoneIds() {
- TimeZoneProviderSuggestion.Builder builder = new TimeZoneProviderSuggestion.Builder()
- .setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS);
- assertRoundTripParcelable(builder.build());
- }
-
- @Test
- public void testParcelable_withTimeZoneIds() {
- TimeZoneProviderSuggestion.Builder builder = new TimeZoneProviderSuggestion.Builder()
- .setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS)
- .setTimeZoneIds(ARBITRARY_TIME_ZONE_IDS);
- assertRoundTripParcelable(builder.build());
- }
-}
diff --git a/core/tests/coretests/src/android/window/WindowContextControllerTest.java b/core/tests/coretests/src/android/window/WindowContextControllerTest.java
index e4fc19c0e58d..020f4a06b892 100644
--- a/core/tests/coretests/src/android/window/WindowContextControllerTest.java
+++ b/core/tests/coretests/src/android/window/WindowContextControllerTest.java
@@ -60,34 +60,39 @@ public class WindowContextControllerTest {
mMockWms = mock(IWindowManager.class);
mController = new WindowContextController(new Binder(), mMockWms);
- doReturn(true).when(mMockWms).registerWindowContextListener(
- any(), anyInt(), anyInt(), any());
+ doReturn(true).when(mMockWms).attachWindowContextToDisplayArea(any(), anyInt(),
+ anyInt(), any());
}
- @Test(expected = UnsupportedOperationException.class)
- public void testRegisterListenerTwiceThrowException() {
- mController.registerListener(TYPE_APPLICATION_OVERLAY, DEFAULT_DISPLAY,
+ @Test(expected = IllegalStateException.class)
+ public void testAttachToDisplayAreaTwiceThrowException() {
+ mController.attachToDisplayArea(TYPE_APPLICATION_OVERLAY, DEFAULT_DISPLAY,
null /* options */);
- mController.registerListener(TYPE_APPLICATION_OVERLAY, DEFAULT_DISPLAY,
+ mController.attachToDisplayArea(TYPE_APPLICATION_OVERLAY, DEFAULT_DISPLAY,
null /* options */);
}
@Test
- public void testUnregisterListenerIfNeeded_NotRegisteredYet_DoNothing() throws Exception {
- mController.unregisterListenerIfNeeded();
+ public void testDetachIfNeeded_NotAttachedYet_DoNothing() throws Exception {
+ mController.detachIfNeeded();
- verify(mMockWms, never()).registerWindowContextListener(any(), anyInt(), anyInt(), any());
+ verify(mMockWms, never()).detachWindowContextFromWindowContainer(any());
}
@Test
- public void testRegisterAndUnRegisterListener() {
- mController.registerListener(TYPE_APPLICATION_OVERLAY, DEFAULT_DISPLAY,
+ public void testAttachAndDetachDisplayArea() {
+ mController.attachToDisplayArea(TYPE_APPLICATION_OVERLAY, DEFAULT_DISPLAY,
null /* options */);
- assertThat(mController.mListenerRegistered).isTrue();
+ assertThat(mController.mAttachedToDisplayArea).isTrue();
- mController.unregisterListenerIfNeeded();
+ mController.detachIfNeeded();
- assertThat(mController.mListenerRegistered).isFalse();
+ assertThat(mController.mAttachedToDisplayArea).isFalse();
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testAttachToWindowTokenBeforeAttachingToDAThrowException() {
+ mController.attachToWindowToken(new Binder());
}
}
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
index 5334a455ce9a..78901683eca1 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
@@ -934,7 +934,7 @@ public class BinderCallsStatsTest {
bcs.elapsedTime += 20;
bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
- assertEquals(1, bcs.getLatencyObserver().getLatencySamples().size());
+ assertEquals(1, bcs.getLatencyObserver().getLatencyHistograms().size());
}
@Test
@@ -948,7 +948,7 @@ public class BinderCallsStatsTest {
bcs.elapsedTime += 20;
bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
- assertEquals(0, bcs.getLatencyObserver().getLatencySamples().size());
+ assertEquals(0, bcs.getLatencyObserver().getLatencyHistograms().size());
}
private static class TestHandler extends Handler {
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderLatencyBucketsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderLatencyBucketsTest.java
new file mode 100644
index 000000000000..00443a967c79
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/BinderLatencyBucketsTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.internal.os;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+public class BinderLatencyBucketsTest {
+ @Test
+ public void testBucketThresholds() {
+ BinderLatencyBuckets latencyBuckets = new BinderLatencyBuckets(10, 2, 1.45f);
+ assertThat(latencyBuckets.getBuckets())
+ .containsExactly(2, 3, 4, 6, 8, 12, 18, 26, 39)
+ .inOrder();
+ }
+
+ @Test
+ public void testSampleAssignment() {
+ BinderLatencyBuckets latencyBuckets = new BinderLatencyBuckets(10, 2, 1.45f);
+ assertEquals(0, latencyBuckets.sampleToBucket(0));
+ assertEquals(0, latencyBuckets.sampleToBucket(1));
+ assertEquals(1, latencyBuckets.sampleToBucket(2));
+ assertEquals(2, latencyBuckets.sampleToBucket(3));
+ assertEquals(3, latencyBuckets.sampleToBucket(4));
+ assertEquals(5, latencyBuckets.sampleToBucket(9));
+ assertEquals(6, latencyBuckets.sampleToBucket(13));
+ assertEquals(7, latencyBuckets.sampleToBucket(25));
+ assertEquals(9, latencyBuckets.sampleToBucket(100));
+ }
+
+ @Test
+ public void testMaxIntBuckets() {
+ BinderLatencyBuckets latencyBuckets = new BinderLatencyBuckets(5, Integer.MAX_VALUE / 2, 2);
+ assertThat(latencyBuckets.getBuckets())
+ .containsExactly(Integer.MAX_VALUE / 2, Integer.MAX_VALUE - 1)
+ .inOrder();
+
+ assertEquals(0, latencyBuckets.sampleToBucket(0));
+ assertEquals(0, latencyBuckets.sampleToBucket(Integer.MAX_VALUE / 2 - 1));
+ assertEquals(1, latencyBuckets.sampleToBucket(Integer.MAX_VALUE - 2));
+ assertEquals(2, latencyBuckets.sampleToBucket(Integer.MAX_VALUE));
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java b/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java
index 36915a205ee0..f65fb9583d6c 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java
@@ -33,7 +33,6 @@ import com.android.internal.os.BinderLatencyObserver.LatencyDims;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
@@ -44,6 +43,7 @@ public class BinderLatencyObserverTest {
@Test
public void testLatencyCollectionWithMultipleClasses() {
TestBinderLatencyObserver blo = new TestBinderLatencyObserver();
+ blo.setHistogramBucketsParams(5, 5, 1.125f);
Binder binder = new Binder();
CallSession callSession = new CallSession();
@@ -51,20 +51,24 @@ public class BinderLatencyObserverTest {
callSession.transactionCode = 1;
blo.callEnded(callSession);
blo.callEnded(callSession);
+ blo.callEnded(callSession);
callSession.transactionCode = 2;
blo.callEnded(callSession);
+ blo.callEnded(callSession);
- ArrayMap<LatencyDims, ArrayList<Long>> latencySamples = blo.getLatencySamples();
- assertEquals(2, latencySamples.keySet().size());
- assertThat(latencySamples.get(new LatencyDims(binder.getClass(), 1)))
- .containsExactlyElementsIn(Arrays.asList(1L, 2L));
- assertThat(latencySamples.get(new LatencyDims(binder.getClass(), 2))).containsExactly(3L);
+ ArrayMap<LatencyDims, int[]> latencyHistograms = blo.getLatencyHistograms();
+ assertEquals(2, latencyHistograms.keySet().size());
+ assertThat(latencyHistograms.get(new LatencyDims(binder.getClass(), 1)))
+ .asList().containsExactly(2, 0, 1, 0, 0).inOrder();
+ assertThat(latencyHistograms.get(new LatencyDims(binder.getClass(), 2)))
+ .asList().containsExactly(0, 0, 0, 0, 2).inOrder();
}
@Test
public void testSampling() {
TestBinderLatencyObserver blo = new TestBinderLatencyObserver();
blo.setSamplingInterval(2);
+ blo.setHistogramBucketsParams(5, 5, 1.125f);
Binder binder = new Binder();
CallSession callSession = new CallSession();
@@ -74,17 +78,58 @@ public class BinderLatencyObserverTest {
callSession.transactionCode = 2;
blo.callEnded(callSession);
- ArrayMap<LatencyDims, ArrayList<Long>> latencySamples = blo.getLatencySamples();
- assertEquals(1, latencySamples.size());
- LatencyDims dims = latencySamples.keySet().iterator().next();
+ ArrayMap<LatencyDims, int[]> latencyHistograms = blo.getLatencyHistograms();
+ assertEquals(1, latencyHistograms.size());
+ LatencyDims dims = latencyHistograms.keySet().iterator().next();
assertEquals(binder.getClass(), dims.getBinderClass());
assertEquals(1, dims.getTransactionCode());
- ArrayList<Long> values = latencySamples.get(dims);
- assertThat(values).containsExactly(1L);
+ assertThat(latencyHistograms.get(dims)).asList().containsExactly(1, 0, 0, 0, 0).inOrder();
+ }
+
+ @Test
+ public void testTooCallLengthOverflow() {
+ TestBinderLatencyObserver blo = new TestBinderLatencyObserver();
+ blo.setElapsedTime(2L + (long) Integer.MAX_VALUE);
+ blo.setHistogramBucketsParams(5, 5, 1.125f);
+
+ Binder binder = new Binder();
+ CallSession callSession = new CallSession();
+ callSession.binderClass = binder.getClass();
+ callSession.transactionCode = 1;
+ blo.callEnded(callSession);
+
+ // The long call should be capped to maxint (to not overflow) and placed in the last bucket.
+ assertThat(blo.getLatencyHistograms()
+ .get(new LatencyDims(binder.getClass(), 1)))
+ .asList().containsExactly(0, 0, 0, 0, 1)
+ .inOrder();
+ }
+
+ @Test
+ public void testHistogramBucketOverflow() {
+ TestBinderLatencyObserver blo = new TestBinderLatencyObserver();
+ blo.setHistogramBucketsParams(3, 5, 1.125f);
+
+ Binder binder = new Binder();
+ CallSession callSession = new CallSession();
+ callSession.binderClass = binder.getClass();
+ callSession.transactionCode = 1;
+ blo.callEnded(callSession);
+
+ LatencyDims dims = new LatencyDims(binder.getClass(), 1);
+ // Fill the buckets with maxint.
+ Arrays.fill(blo.getLatencyHistograms().get(dims), Integer.MAX_VALUE);
+ assertThat(blo.getLatencyHistograms().get(dims))
+ .asList().containsExactly(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
+ // Try to add another sample.
+ blo.callEnded(callSession);
+ // Make sure the buckets don't overflow.
+ assertThat(blo.getLatencyHistograms().get(dims))
+ .asList().containsExactly(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
}
public static class TestBinderLatencyObserver extends BinderLatencyObserver {
- private long mElapsedTimeCallCount = 0;
+ private long mElapsedTime = 0;
TestBinderLatencyObserver() {
// Make random generator not random.
@@ -104,7 +149,12 @@ public class BinderLatencyObserverTest {
@Override
protected long getElapsedRealtimeMicro() {
- return ++mElapsedTimeCallCount;
+ mElapsedTime += 2;
+ return mElapsedTime;
+ }
+
+ public void setElapsedTime(long time) {
+ mElapsedTime = time;
}
}
}
diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
index 0808186b21c5..269d8424a78f 100644
--- a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
+++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
@@ -298,7 +298,8 @@ public class ActivityThreadClientTest {
null /* pendingResults */, null /* pendingNewIntents */,
null /* activityOptions */, true /* isForward */, null /* profilerInfo */,
mThread /* client */, null /* asssitToken */,
- null /* fixedRotationAdjustments */, null /* shareableActivityToken */);
+ null /* fixedRotationAdjustments */, null /* shareableActivityToken */,
+ false /* launchedFromBubble */);
}
@Override
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 1c11f9557d81..71fc29b04a80 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -284,7 +284,8 @@
<allow-in-power-save package="com.android.shell" />
<!-- Whitelist system providers -->
- <allow-in-power-save-except-idle package="com.android.providers.calendar" />
+ <!-- Calendar provider needs alarms while in idle -->
+ <allow-in-power-save package="com.android.providers.calendar" />
<allow-in-power-save-except-idle package="com.android.providers.contacts" />
<!-- The PAC proxy process must have network access, otherwise no app will
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index efeaf238ac84..fec78f070311 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -2029,12 +2029,6 @@
"group": "WM_DEBUG_WINDOW_ORGANIZER",
"at": "com\/android\/server\/wm\/TaskOrganizerController.java"
},
- "236210101": {
- "message": "registerWindowContextListener: trying to add listener to a non-existing display:%d",
- "level": "WARN",
- "group": "WM_ERROR",
- "at": "com\/android\/server\/wm\/WindowManagerService.java"
- },
"240271590": {
"message": "moveFocusableActivityToTop: unfocusable activity=%s",
"level": "DEBUG",
@@ -2473,6 +2467,12 @@
"group": "WM_DEBUG_SCREEN_ON",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "666937535": {
+ "message": "attachWindowContextToDisplayArea: trying to attach to a non-existing display:%d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
"674932310": {
"message": "Setting Intent of %s to target %s",
"level": "VERBOSE",
@@ -3307,6 +3307,12 @@
"group": "WM_DEBUG_RECENTS_ANIMATIONS",
"at": "com\/android\/server\/wm\/RecentsAnimation.java"
},
+ "1789321832": {
+ "message": "Then token:%s is invalid. It might be removed",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
"1789603530": {
"message": "Removing activity %s hasSavedState=%b stateNotNeeded=%s finishing=%b state=%s callers=%s",
"level": "INFO",
diff --git a/data/keyboards/Vendor_054c_Product_0ce6.kl b/data/keyboards/Vendor_054c_Product_0ce6.kl
new file mode 100644
index 000000000000..4d51a9ecdce2
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0ce6.kl
@@ -0,0 +1,71 @@
+# 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.
+
+#
+# Sony Playstation(R) DualSense Controller
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Square
+key 0x134 BUTTON_X
+# Cross
+key 0x130 BUTTON_A
+# Circle
+key 0x131 BUTTON_B
+# Triangle
+key 0x133 BUTTON_Y
+
+key 0x136 BUTTON_L1
+key 0x137 BUTTON_R1
+key 0x138 BUTTON_L2
+key 0x139 BUTTON_R2
+
+# L2 axis
+axis 0x02 LTRIGGER
+# R2 axis
+axis 0x05 RTRIGGER
+
+# Left Analog Stick
+axis 0x00 X
+axis 0x01 Y
+# Right Analog Stick
+axis 0x03 Z
+axis 0x04 RZ
+
+# Left stick click
+key 0x13d BUTTON_THUMBL
+# Right stick click
+key 0x13e BUTTON_THUMBR
+
+# Hat
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Share
+key 0x13a BUTTON_SELECT
+# Options
+key 0x13b BUTTON_START
+# PS key
+key 0x13c BUTTON_MODE
+
+# SENSORs
+sensor 0x00 ACCELEROMETER X
+sensor 0x01 ACCELEROMETER Y
+sensor 0x02 ACCELEROMETER Z
+sensor 0x03 GYROSCOPE X
+sensor 0x04 GYROSCOPE Y
+sensor 0x05 GYROSCOPE Z
diff --git a/data/keyboards/Vendor_0957_Product_0001.idc b/data/keyboards/Vendor_0957_Product_0001.idc
index 39479ce725e1..c67e6d34fccb 100644
--- a/data/keyboards/Vendor_0957_Product_0001.idc
+++ b/data/keyboards/Vendor_0957_Product_0001.idc
@@ -19,4 +19,5 @@
# Basic Parameters
keyboard.layout = Vendor_0957_Product_0001
+keyboard.doNotWakeByDefault = 1
audio.mic = 1 \ No newline at end of file
diff --git a/data/keyboards/Vendor_0957_Product_0001.kl b/data/keyboards/Vendor_0957_Product_0001.kl
index 90c0433d2a9c..672abef3c963 100644
--- a/data/keyboards/Vendor_0957_Product_0001.kl
+++ b/data/keyboards/Vendor_0957_Product_0001.kl
@@ -47,7 +47,7 @@ key 11 0
key usage 0x000c01BB TV_INPUT
key usage 0x000c022A BOOKMARK
key usage 0x000c0096 SETTINGS
-key usage 0x000c0097 NOTIFICATION
+key usage 0x000c009F NOTIFICATION
key usage 0x000c008D GUIDE
key usage 0x000c0089 TV
key usage 0x000c009C CHANNEL_UP
diff --git a/data/keyboards/Vendor_248a_Product_8266.idc b/data/keyboards/Vendor_248a_Product_8266.idc
index 3021655c286e..47ff9f88374f 100644
--- a/data/keyboards/Vendor_248a_Product_8266.idc
+++ b/data/keyboards/Vendor_248a_Product_8266.idc
@@ -21,4 +21,5 @@
# Due to a memory error on early prototypes of the reference remote control
# the VID/PID is mapped to 248a/8266 instead of 0957/0001
keyboard.layout = Vendor_0957_Product_0001
+keyboard.doNotWakeByDefault = 1
audio.mic = 1 \ No newline at end of file
diff --git a/graphics/java/android/graphics/FrameInfo.java b/graphics/java/android/graphics/FrameInfo.java
index 189be53a397f..786c03ba5150 100644
--- a/graphics/java/android/graphics/FrameInfo.java
+++ b/graphics/java/android/graphics/FrameInfo.java
@@ -87,18 +87,22 @@ public final class FrameInfo {
// When the frame needs to be ready by
public static final int FRAME_DEADLINE = 9;
+ // When frame actually started.
+ public static final int FRAME_START_TIME = 10;
+
// Must be the last one
// This value must be in sync with `UI_THREAD_FRAME_INFO_SIZE` in FrameInfo.h
- private static final int FRAME_INFO_SIZE = FRAME_DEADLINE + 1;
+ private static final int FRAME_INFO_SIZE = FRAME_START_TIME + 1;
/** checkstyle */
public void setVsync(long intendedVsync, long usedVsync, long frameTimelineVsyncId,
- long frameDeadline) {
+ long frameDeadline, long frameStartTime) {
frameInfo[FRAME_TIMELINE_VSYNC_ID] = frameTimelineVsyncId;
frameInfo[INTENDED_VSYNC] = intendedVsync;
frameInfo[VSYNC] = usedVsync;
frameInfo[FLAGS] = 0;
frameInfo[FRAME_DEADLINE] = frameDeadline;
+ frameInfo[FRAME_START_TIME] = frameStartTime;
}
/** checkstyle */
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index 88cf96a9eb4e..7589435fc3b7 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -28,6 +28,7 @@ import android.content.res.Configuration;
import android.hardware.display.DisplayManager;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
+import android.os.PerformanceHintManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
@@ -165,7 +166,7 @@ public class HardwareRenderer {
* to opaque with no light source configured.
*/
public HardwareRenderer() {
- ProcessInitializer.sInstance.initDisplayInfo();
+ ProcessInitializer.sInstance.initUsingContext();
mRootNode = RenderNode.adopt(nCreateRootRenderNode());
mRootNode.setClipToBounds(false);
mNativeProxy = nCreateProxy(!mOpaque, mRootNode.mNativeRenderNode);
@@ -365,7 +366,8 @@ public class HardwareRenderer {
*/
public @NonNull FrameRenderRequest setVsyncTime(long vsyncTime) {
// TODO(b/168552873): populate vsync Id once available to Choreographer public API
- mFrameInfo.setVsync(vsyncTime, vsyncTime, FrameInfo.INVALID_VSYNC_ID, Long.MAX_VALUE);
+ mFrameInfo.setVsync(vsyncTime, vsyncTime, FrameInfo.INVALID_VSYNC_ID, Long.MAX_VALUE,
+ vsyncTime);
mFrameInfo.addFlags(FrameInfo.FLAG_SURFACE_CANVAS);
return this;
}
@@ -835,6 +837,36 @@ public class HardwareRenderer {
callback.onPictureCaptured(picture);
}
+ /** called by native */
+ static PerformanceHintManager.Session createHintSession(int[] tids) {
+ PerformanceHintManager performanceHintManager =
+ ProcessInitializer.sInstance.getHintManager();
+ if (performanceHintManager == null) {
+ return null;
+ }
+ // Native code will always set a target duration before reporting actual durations.
+ // So this is just a placeholder value that's never used.
+ long targetDurationNanos = 16666667;
+ return performanceHintManager.createHintSession(tids, targetDurationNanos);
+ }
+
+ /** called by native */
+ static void updateTargetWorkDuration(PerformanceHintManager.Session session,
+ long targetDurationNanos) {
+ session.updateTargetWorkDuration(targetDurationNanos);
+ }
+
+ /** called by native */
+ static void reportActualWorkDuration(PerformanceHintManager.Session session,
+ long actualDurationNanos) {
+ session.reportActualWorkDuration(actualDurationNanos);
+ }
+
+ /** called by native */
+ static void closeHintSession(PerformanceHintManager.Session session) {
+ session.close();
+ }
+
/**
* Interface used to receive callbacks when a frame is being drawn.
*
@@ -1071,6 +1103,7 @@ public class HardwareRenderer {
private boolean mIsolated = false;
private Context mContext;
private String mPackageName;
+ private PerformanceHintManager mPerformanceHintManager;
private IGraphicsStats mGraphicsStatsService;
private IGraphicsStatsCallback mGraphicsStatsCallback = new IGraphicsStatsCallback.Stub() {
@Override
@@ -1082,6 +1115,10 @@ public class HardwareRenderer {
private ProcessInitializer() {
}
+ synchronized PerformanceHintManager getHintManager() {
+ return mPerformanceHintManager;
+ }
+
synchronized void setPackageName(String name) {
if (mInitialized) return;
mPackageName = name;
@@ -1127,15 +1164,23 @@ public class HardwareRenderer {
}
}
- synchronized void initDisplayInfo() {
- if (mDisplayInitialized) return;
+ synchronized void initUsingContext() {
if (mContext == null) return;
- // If we're in an isolated sandbox mode then we shouldn't try to communicate with DMS
+ initDisplayInfo();
+
+ // HintManager and HintSession are designed to be accessible from isoalted processes
+ // so not checking for isolated process here.
+ initHintSession();
+
+ // Defensively clear out the context in case we were passed a context that can leak
+ // if we live longer than it, e.g. an activity context.
+ mContext = null;
+ }
+
+ private void initDisplayInfo() {
+ if (mDisplayInitialized) return;
if (mIsolated) {
- // Defensively clear out the context in case we were passed a context that can leak
- // if we live longer than it, e.g. an activity context.
- mContext = null;
mDisplayInitialized = true;
return;
}
@@ -1167,11 +1212,14 @@ public class HardwareRenderer {
display.getRefreshRate(), wideColorDataspace.mNativeDataspace,
display.getAppVsyncOffsetNanos(), display.getPresentationDeadlineNanos());
- // Defensively clear out the context
- mContext = null;
mDisplayInitialized = true;
}
+ private void initHintSession() {
+ if (mContext == null) return;
+ mPerformanceHintManager = mContext.getSystemService(PerformanceHintManager.class);
+ }
+
private void rotateBuffer() {
nRotateProcessStatsBuffer();
requestBuffer();
diff --git a/libs/WindowManager/Shell/lint-baseline.xml b/libs/WindowManager/Shell/lint-baseline.xml
new file mode 100644
index 000000000000..06094ffe1930
--- /dev/null
+++ b/libs/WindowManager/Shell/lint-baseline.xml
@@ -0,0 +1,5471 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" return mRootTaskInfo != null ? mRootTaskInfo.taskId : INVALID_TASK_ID;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="73"
+ column="40"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" return mTaskInfo1 != null ? mTaskInfo1.taskId : INVALID_TASK_ID;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="77"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" return mTaskInfo2 != null ? mTaskInfo2.taskId : INVALID_TASK_ID;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="81"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = task1.taskId; long protoLogParam1 = task2.taskId; String protoLogParam2 = String.valueOf(this); com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, -742394458, 5, null, protoLogParam0, protoLogParam1, protoLogParam2); "
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="89"
+ column="113"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = task1.taskId; long protoLogParam1 = task2.taskId; String protoLogParam2 = String.valueOf(this); com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, -742394458, 5, null, protoLogParam0, protoLogParam1, protoLogParam2); "
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="89"
+ column="149"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" b -> b.setParent(mRootTaskLeash), mDisplayImeController);"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="105"
+ column="24"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (mRootTaskInfo == null || taskInfo.taskId == mRootTaskInfo.taskId) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="151"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (mRootTaskInfo == null || taskInfo.taskId == mRootTaskInfo.taskId) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="151"
+ column="57"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" } else if (taskInfo.taskId == getTaskId1()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="154"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" } else if (taskInfo.taskId == getTaskId2()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="157"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" throw new IllegalStateException(&quot;Unknown task=&quot; + taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="161"
+ column="63"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(dividerLeash, Integer.MAX_VALUE)"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="172"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (taskInfo.taskId == getRootTaskId()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="186"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" } else if (taskInfo.taskId == getTaskId1()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="202"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" } else if (taskInfo.taskId == getTaskId2()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="204"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" throw new IllegalStateException(&quot;Unknown task=&quot; + taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="207"
+ column="63"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (taskInfo.taskId == getRootTaskId()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="213"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" mController.unpair(mRootTaskInfo.taskId, false /* releaseToPool */);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="215"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" } else if (taskInfo.taskId == getTaskId1() || taskInfo.taskId == getTaskId2()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="216"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" } else if (taskInfo.taskId == getTaskId1() || taskInfo.taskId == getTaskId2()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="216"
+ column="55"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" mController.unpair(mRootTaskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="217"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" b.setParent(mRootTaskLeash);"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="224"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" b.setParent(mTaskLeash1);"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="226"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" b.setParent(mTaskLeash2);"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="228"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" pw.println(innerPrefix + &quot;1 taskId=&quot; + mTaskInfo1.taskId"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="242"
+ column="52"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" pw.println(innerPrefix + &quot;2 taskId=&quot; + mTaskInfo2.taskId"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="246"
+ column="52"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" .setLayer(dividerLeash, Integer.MAX_VALUE)"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java"
+ line="291"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.content.LocusId`"
+ errorLine1=" mLocusId = locus != null ? new LocusId(locus) : null;"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java"
+ line="177"
+ column="36"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.service.notification.StatusBarNotification#getUid`"
+ errorLine1=" mAppUid = entry.getStatusBarNotification().getUid();"
+ errorLine2=" ~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java"
+ line="449"
+ column="52"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 26): `android.service.notification.NotificationListenerService.Ranking#getConversationShortcutInfo`"
+ errorLine1=" mShortcutInfo = entry.getRanking().getConversationShortcutInfo();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java"
+ line="453"
+ column="48"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.app.NotificationChannel#isImportantConversation`"
+ errorLine1=" entry.getRanking().getChannel().isImportantConversation();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java"
+ line="457"
+ column="57"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.app.Notification.BubbleMetadata#getShortcutId`"
+ errorLine1=" mMetadataShortcutId = entry.getBubbleMetadata().getShortcutId();"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java"
+ line="461"
+ column="61"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.app.Notification.BubbleMetadata#getDesiredHeight`"
+ errorLine1=" mDesiredHeight = entry.getBubbleMetadata().getDesiredHeight();"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java"
+ line="463"
+ column="56"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.app.Notification.BubbleMetadata#getDesiredHeightResId`"
+ errorLine1=" mDesiredHeightResId = entry.getBubbleMetadata().getDesiredHeightResId();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java"
+ line="464"
+ column="61"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.app.Notification.BubbleMetadata#getIcon`"
+ errorLine1=" mIcon = entry.getBubbleMetadata().getIcon();"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java"
+ line="465"
+ column="47"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.app.Notification.BubbleMetadata#getIntent`"
+ errorLine1=" mIntent = entry.getBubbleMetadata().getIntent();"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java"
+ line="471"
+ column="53"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.app.Notification.BubbleMetadata#getIntent`"
+ errorLine1=" } else if (mIntent != null &amp;&amp; entry.getBubbleMetadata().getIntent() == null) {"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java"
+ line="475"
+ column="69"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.app.Notification.BubbleMetadata#getDeleteIntent`"
+ errorLine1=" mDeleteIntent = entry.getBubbleMetadata().getDeleteIntent();"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java"
+ line="481"
+ column="55"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.app.Notification.MessagingStyle.Message#getMessagesFromBundleArray`"
+ errorLine1=" Notification.MessagingStyle.Message.getMessagesFromBundleArray("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java"
+ line="856"
+ column="61"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 26): `android.app.Notification.MessagingStyle.Message#getSenderPerson`"
+ errorLine1=" Person sender = latestMessage.getSenderPerson();"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java"
+ line="864"
+ column="51"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 26): `android.app.Person#getName`"
+ errorLine1=" bubbleMessage.senderName = sender != null ? sender.getName() : null;"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java"
+ line="865"
+ column="72"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 26): `android.app.Person#getIcon`"
+ errorLine1=" bubbleMessage.senderIcon = sender != null ? sender.getIcon() : null;"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java"
+ line="867"
+ column="72"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (task.taskId == b.getTaskId()) {"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java"
+ line="357"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#setFitInsetsTypes`"
+ errorLine1=" mWmLayoutParams.setFitInsetsTypes(0);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java"
+ line="553"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 28 (current min is 26): `android.view.WindowManager.LayoutParams#layoutInDisplayCutoutMode`"
+ errorLine1=" mWmLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java"
+ line="558"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.app.Notification.BubbleMetadata#getAutoExpandBubble`"
+ errorLine1=" &amp;&amp; !notif.getBubbleMetadata().getAutoExpandBubble())"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java"
+ line="842"
+ column="51"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.service.notification.NotificationListenerService.Ranking#canBubble`"
+ errorLine1=" if (isActiveBubble &amp;&amp; !mTmpRanking.canBubble()) {"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java"
+ line="919"
+ column="48"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.app.Notification.BubbleMetadata#getIntent`"
+ errorLine1=" ? entry.getBubbleMetadata().getIntent()"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java"
+ line="1217"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.app.Notification.BubbleMetadata#getShortcutId`"
+ errorLine1=" &amp;&amp; entry.getBubbleMetadata().getShortcutId() != null) {"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java"
+ line="1220"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.content.LocusId#getId`"
+ errorLine1=" b.locusId?.id"
+ errorLine2=" ~~">
+ <location
+ file="frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt"
+ line="85"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.app.Notification#getLocusId`"
+ errorLine1=" return mSbn.getNotification().getLocusId();"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEntry.java"
+ line="81"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.app.Notification#getBubbleMetadata`"
+ errorLine1=" return getStatusBarNotification().getNotification().getBubbleMetadata();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEntry.java"
+ line="87"
+ column="61"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.service.notification.NotificationListenerService.Ranking#canBubble`"
+ errorLine1=" return mRanking.canBubble();"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEntry.java"
+ line="115"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 26): `android.graphics.Bitmap#createBitmap`"
+ errorLine1=" Bitmap snapshot = Bitmap.createBitmap(p);"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java"
+ line="428"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 26): `android.graphics.Bitmap#getHardwareBuffer`"
+ errorLine1=" return new SurfaceControl.ScreenshotHardwareBuffer(snapshot.getHardwareBuffer(),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java"
+ line="429"
+ column="73"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceView#getSurfaceControl`"
+ errorLine1=" if (mTaskView == null || mTaskView.getSurfaceControl() == null) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java"
+ line="432"
+ column="44"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceView#getSurfaceControl`"
+ errorLine1=" mTaskView.getSurfaceControl(),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java"
+ line="436"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#top`"
+ errorLine1=" ? mExpandedViewContainerLocation[1] - mPositioner.getInsets().top"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java"
+ line="636"
+ column="55"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.graphics.Outline#setPath`"
+ errorLine1=" outline.setPath(rectPath);"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java"
+ line="504"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 26): `android.graphics.drawable.Icon#getType`"
+ errorLine1=" if (ic.getType() == Icon.TYPE_URI"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java"
+ line="65"
+ column="24"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 26): `android.graphics.drawable.Icon#getType`"
+ errorLine1=" || ic.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) {"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java"
+ line="66"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 26): `android.graphics.drawable.Icon#getUri`"
+ errorLine1=" ic.getUri(),"
+ errorLine2=" ~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java"
+ line="68"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`"
+ errorLine1=" getContext().getDisplay().getMetrics(displayMetrics);"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java"
+ line="143"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowManager#getCurrentWindowMetrics`"
+ errorLine1=" WindowMetrics windowMetrics = mWindowManager.getCurrentWindowMetrics();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="93"
+ column="54"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowMetrics#getWindowInsets`"
+ errorLine1=" WindowInsets metricInsets = windowMetrics.getWindowInsets();"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="97"
+ column="51"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowInsets#getInsetsIgnoringVisibility`"
+ errorLine1=" Insets insets = metricInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="99"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#navigationBars`"
+ errorLine1=" Insets insets = metricInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="99"
+ column="84"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#statusBars`"
+ errorLine1=" | WindowInsets.Type.statusBars()"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="100"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#displayCutout`"
+ errorLine1=" | WindowInsets.Type.displayCutout());"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="101"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowMetrics#getBounds`"
+ errorLine1=" + &quot; bounds: &quot; + windowMetrics.getBounds()"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="107"
+ column="51"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowMetrics#getBounds`"
+ errorLine1=" updateInternal(orientation, insets, windowMetrics.getBounds());"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="110"
+ column="59"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#left`"
+ errorLine1=" mPositionRect.left += mInsets.left;"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="134"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#top`"
+ errorLine1=" mPositionRect.top += mInsets.top;"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="135"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#right`"
+ errorLine1=" mPositionRect.right -= mInsets.right;"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="136"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#bottom`"
+ errorLine1=" mPositionRect.bottom -= mInsets.bottom;"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="137"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowManager#getCurrentWindowMetrics`"
+ errorLine1=" WindowInsets metricInsets = mWindowManager.getCurrentWindowMetrics().getWindowInsets();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="156"
+ column="56"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowMetrics#getWindowInsets`"
+ errorLine1=" WindowInsets metricInsets = mWindowManager.getCurrentWindowMetrics().getWindowInsets();"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="156"
+ column="82"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowInsets#getInsetsIgnoringVisibility`"
+ errorLine1=" Insets navBarInsets = metricInsets.getInsetsIgnoringVisibility("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="157"
+ column="48"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#navigationBars`"
+ errorLine1=" WindowInsets.Type.navigationBars());"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="158"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#left`"
+ errorLine1=" int newInsetLeft = mInsets.left;"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="159"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#right`"
+ errorLine1=" int newInsetRight = mInsets.right;"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="160"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#left`"
+ errorLine1=" mPositionRect.left -= navBarInsets.left;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="162"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#left`"
+ errorLine1=" newInsetLeft -= navBarInsets.left;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="163"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#right`"
+ errorLine1=" mPositionRect.right += navBarInsets.right;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="165"
+ column="40"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#right`"
+ errorLine1=" newInsetRight -= navBarInsets.right;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="166"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.graphics.Insets#of`"
+ errorLine1=" mInsets = Insets.of(newInsetLeft, mInsets.top, newInsetRight, mInsets.bottom);"
+ errorLine2=" ~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="168"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#bottom`"
+ errorLine1=" mInsets = Insets.of(newInsetLeft, mInsets.top, newInsetRight, mInsets.bottom);"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="168"
+ column="75"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#top`"
+ errorLine1=" mInsets = Insets.of(newInsetLeft, mInsets.top, newInsetRight, mInsets.bottom);"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="168"
+ column="47"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `new android.graphics.PointF`"
+ errorLine1=" mRestingStackPosition = new PointF(position);"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java"
+ line="229"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.View#getAnimationMatrix`"
+ errorLine1=" pw.println(mExpandedViewContainer.getAnimationMatrix());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java"
+ line="295"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.View#setSystemGestureExclusionRects`"
+ errorLine1=" mBubbleContainer.setSystemGestureExclusionRects(mSystemGestureExclusionRects);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java"
+ line="1427"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.View#setSystemGestureExclusionRects`"
+ errorLine1=" mBubbleContainer.setSystemGestureExclusionRects(Collections.emptyList());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java"
+ line="1430"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.View#setAnimationMatrix`"
+ errorLine1=" mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix))"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java"
+ line="1750"
+ column="48"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.View#setAnimationMatrix`"
+ errorLine1=" mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix))"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java"
+ line="1775"
+ column="48"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.View#setAnimationMatrix`"
+ errorLine1=" mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java"
+ line="1863"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.View#setAnimationMatrix`"
+ errorLine1=" mExpandedViewContainer.setAnimationMatrix("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java"
+ line="1894"
+ column="48"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.View#setAnimationMatrix`"
+ errorLine1=" mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java"
+ line="1986"
+ column="44"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.View#setAnimationMatrix`"
+ errorLine1=" mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java"
+ line="2074"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.View#setAnimationMatrix`"
+ errorLine1=" mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java"
+ line="2091"
+ column="48"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.View#setAnimationMatrix`"
+ errorLine1=" mExpandedViewContainer.setAnimationMatrix(null);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java"
+ line="2118"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#left`"
+ errorLine1=" int leftPadding = insets.left + mExpandedViewPadding;"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java"
+ line="2696"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#right`"
+ errorLine1=" int rightPadding = insets.right + mExpandedViewPadding;"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java"
+ line="2697"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 26): `android.graphics.drawable.Icon#getType`"
+ errorLine1=" if (icon.getType() == Icon.TYPE_URI || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) {"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java"
+ line="220"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 26): `android.graphics.drawable.Icon#getType`"
+ errorLine1=" if (icon.getType() == Icon.TYPE_URI || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) {"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java"
+ line="220"
+ column="53"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 26): `android.graphics.drawable.Icon#getUri`"
+ errorLine1=" icon.getUri(), Intent.FLAG_GRANT_READ_URI_PERMISSION);"
+ errorLine2=" ~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java"
+ line="222"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java"
+ line="119"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(leash, transformation.getAlpha());"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java"
+ line="237"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java"
+ line="239"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java"
+ line="279"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#ime`"
+ errorLine1=" if ((types &amp; WindowInsets.Type.ime()) == 0) {"
+ errorLine2=" ~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java"
+ line="285"
+ column="44"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#ime`"
+ errorLine1=" if ((types &amp; WindowInsets.Type.ime()) == 0) {"
+ errorLine2=" ~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java"
+ line="294"
+ column="44"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(mImeSourceControl.getLeash(), alpha);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java"
+ line="396"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java"
+ line="398"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(mImeSourceControl.getLeash(), alpha);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java"
+ line="420"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java"
+ line="424"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(mImeSourceControl.getLeash(), 1.f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java"
+ line="439"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java"
+ line="446"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 26): `android.view.DisplayCutout#getSafeInsetLeft`"
+ errorLine1=" outInsets.left += displayCutout.getSafeInsetLeft();"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="313"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 26): `android.view.DisplayCutout#getSafeInsetTop`"
+ errorLine1=" outInsets.top += displayCutout.getSafeInsetTop();"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="314"
+ column="44"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 26): `android.view.DisplayCutout#getSafeInsetRight`"
+ errorLine1=" outInsets.right += displayCutout.getSafeInsetRight();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="315"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 26): `android.view.DisplayCutout#getSafeInsetBottom`"
+ errorLine1=" outInsets.bottom += displayCutout.getSafeInsetBottom();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="316"
+ column="47"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.DisplayCutout#getWaterfallInsets`"
+ errorLine1=" final Insets waterfallInsets = rotateInsets(cutout.getWaterfallInsets(), rotation);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="358"
+ column="60"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.DisplayCutout#getWaterfallInsets`"
+ errorLine1=" int leftInset = Math.max(cutout.getWaterfallInsets().left,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="405"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#left`"
+ errorLine1=" int leftInset = Math.max(cutout.getWaterfallInsets().left,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="405"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.DisplayCutout#getBoundingRectLeft`"
+ errorLine1=" findCutoutInsetForSide(displaySize, cutout.getBoundingRectLeft(), Gravity.LEFT));"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="406"
+ column="60"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.DisplayCutout#getWaterfallInsets`"
+ errorLine1=" int topInset = Math.max(cutout.getWaterfallInsets().top,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="407"
+ column="40"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#top`"
+ errorLine1=" int topInset = Math.max(cutout.getWaterfallInsets().top,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="407"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.DisplayCutout#getBoundingRectTop`"
+ errorLine1=" findCutoutInsetForSide(displaySize, cutout.getBoundingRectTop(), Gravity.TOP));"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="408"
+ column="60"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.DisplayCutout#getWaterfallInsets`"
+ errorLine1=" int rightInset = Math.max(cutout.getWaterfallInsets().right,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="409"
+ column="42"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#right`"
+ errorLine1=" int rightInset = Math.max(cutout.getWaterfallInsets().right,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="409"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.DisplayCutout#getBoundingRectRight`"
+ errorLine1=" findCutoutInsetForSide(displaySize, cutout.getBoundingRectRight(), Gravity.RIGHT));"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="410"
+ column="60"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.DisplayCutout#getWaterfallInsets`"
+ errorLine1=" int bottomInset = Math.max(cutout.getWaterfallInsets().bottom,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="411"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#bottom`"
+ errorLine1=" int bottomInset = Math.max(cutout.getWaterfallInsets().bottom,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="411"
+ column="36"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.DisplayCutout#getBoundingRectBottom`"
+ errorLine1=" findCutoutInsetForSide(displaySize, cutout.getBoundingRectBottom(),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java"
+ line="412"
+ column="60"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java"
+ line="343"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java"
+ line="359"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java"
+ line="406"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java"
+ line="731"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java"
+ line="800"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java"
+ line="878"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(dim, alpha);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java"
+ line="1065"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java"
+ line="1106"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java"
+ line="1171"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 28 (current min is 26): `android.view.WindowManager.LayoutParams#layoutInDisplayCutoutMode`"
+ errorLine1=" mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerWindowManager.java"
+ line="64"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java"
+ line="73"
+ column="61"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.content.Context#createWindowContext`"
+ errorLine1=" .createWindowContext(TYPE_APPLICATION_OVERLAY, null);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java"
+ line="89"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 28 (current min is 26): `android.view.WindowManager.LayoutParams#layoutInDisplayCutoutMode`"
+ errorLine1=" layoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java"
+ line="101"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#setFitInsetsTypes`"
+ errorLine1=" layoutParams.setFitInsetsTypes(0);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java"
+ line="102"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`"
+ errorLine1=" mTransaction.reparent(dragSurface, null);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java"
+ line="229"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" mTransaction.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java"
+ line="230"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#left`"
+ errorLine1=" final int iw = w - insets.left - insets.right;"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java"
+ line="126"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#right`"
+ errorLine1=" final int iw = w - insets.left - insets.right;"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java"
+ line="126"
+ column="42"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#bottom`"
+ errorLine1=" final int ih = h - insets.top - insets.bottom;"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java"
+ line="127"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#top`"
+ errorLine1=" final int ih = h - insets.top - insets.bottom;"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java"
+ line="127"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#left`"
+ errorLine1=" final int l = insets.left;"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java"
+ line="128"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#top`"
+ errorLine1=" final int t = insets.top;"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java"
+ line="129"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" runningTaskId = task.taskId;"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java"
+ line="279"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#NONE`"
+ errorLine1=" private Insets mInsets = Insets.NONE;"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java"
+ line="59"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowInsets#getInsets`"
+ errorLine1=" mInsets = insets.getInsets(Type.systemBars() | Type.displayCutout());"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java"
+ line="76"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#displayCutout`"
+ errorLine1=" mInsets = insets.getInsets(Type.systemBars() | Type.displayCutout());"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java"
+ line="76"
+ column="61"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#systemBars`"
+ errorLine1=" mInsets = insets.getInsets(Type.systemBars() | Type.displayCutout());"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java"
+ line="76"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 26): `com.google.android.collect.Sets#newHashSet`"
+ errorLine1=" return Sets.newHashSet("
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java"
+ line="498"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (mLeashByTaskId.get(taskInfo.taskId) != null) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java"
+ line="53"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" throw new IllegalStateException(&quot;Task appeared more than once: #&quot; + taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java"
+ line="54"
+ column="81"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = taskInfo.taskId; com.android.wm.shell.protolog.ShellProtoLogImpl.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, -1501874464, 1, null, protoLogParam0); "
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java"
+ line="56"
+ column="113"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" mLeashByTaskId.put(taskInfo.taskId, leash);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java"
+ line="58"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(leash, 1f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java"
+ line="66"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java"
+ line="75"
+ column="57"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (mLeashByTaskId.get(taskInfo.taskId) == null) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java"
+ line="88"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" Slog.e(TAG, &quot;Task already vanished: #&quot; + taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java"
+ line="89"
+ column="54"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" mLeashByTaskId.remove(taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java"
+ line="92"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = taskInfo.taskId; com.android.wm.shell.protolog.ShellProtoLogImpl.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, 564235578, 1, null, protoLogParam0); "
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java"
+ line="93"
+ column="113"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.util.SparseArray#contains`"
+ errorLine1=" if (!mLeashByTaskId.contains(taskId)) {"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java"
+ line="99"
+ column="29"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" b.setParent(mLeashByTaskId.get(taskId));"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java"
+ line="102"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.os.Handler#hasCallbacks`"
+ errorLine1=" return mHandler.hasCallbacks(r);"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java"
+ line="55"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" final SurfaceControl.Transaction t = new SurfaceControl.Transaction();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java"
+ line="86"
+ column="54"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java"
+ line="90"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java"
+ line="107"
+ column="47"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" final SurfaceControl.Transaction t = new SurfaceControl.Transaction();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java"
+ line="121"
+ column="50"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" final SurfaceControl.Transaction t = new SurfaceControl.Transaction();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java"
+ line="167"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#NONE`"
+ errorLine1=" return Insets.NONE;"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java"
+ line="185"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.Display#getCutout`"
+ errorLine1=" DisplayCutout cutout = display.getCutout();"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java"
+ line="187"
+ column="40"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.graphics.Insets#of`"
+ errorLine1=" Insets insets = cutout != null ? Insets.of(cutout.getSafeInsets()) : Insets.NONE;"
+ errorLine2=" ~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java"
+ line="188"
+ column="49"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#NONE`"
+ errorLine1=" Insets insets = cutout != null ? Insets.of(cutout.getSafeInsets()) : Insets.NONE;"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java"
+ line="188"
+ column="78"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 26): `android.graphics.Rect#inset`"
+ errorLine1=" mCurrentDisplayBounds.inset(mCurrentCutoutInsets);"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java"
+ line="239"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#top`"
+ errorLine1=" if (mCurrentCutoutInsets.top != 0) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java"
+ line="244"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.Insets#top`"
+ errorLine1=" mCurrentDisplayBounds.top = Math.max(mStatusBarHeight, mCurrentCutoutInsets.top);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java"
+ line="245"
+ column="72"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java"
+ line="287"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`"
+ errorLine1=" mContext.getResources().getFloat("
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java"
+ line="465"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { String protoLogParam0 = String.valueOf(TAG); long protoLogParam1 = taskInfo.taskId; com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, -1362429294, 4, null, protoLogParam0, protoLogParam1); "
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="129"
+ column="166"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { String protoLogParam0 = String.valueOf(TAG); long protoLogParam1 = taskInfo.taskId; com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, 982027396, 4, null, protoLogParam0, protoLogParam1); "
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="134"
+ column="166"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { String protoLogParam0 = String.valueOf(TAG); long protoLogParam1 = taskInfo.taskId; long protoLogParam2 = winMode; com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, -298656957, 20, null, protoLogParam0, protoLogParam1, protoLogParam2); "
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="139"
+ column="166"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" .setParent(mPrimarySurface).setColorLayer()"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="150"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setName`"
+ errorLine1=" .setName(&quot;Primary Divider Dim&quot;)"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="151"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#build`"
+ errorLine1=" .build();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="153"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" .setParent(mSecondarySurface).setColorLayer()"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="155"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setName`"
+ errorLine1=" .setName(&quot;Secondary Divider Dim&quot;)"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="156"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#build`"
+ errorLine1=" .build();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="158"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(mPrimaryDim, Integer.MAX_VALUE);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="160"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(mSecondaryDim, Integer.MAX_VALUE);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="162"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="164"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" mPositionByTaskId.remove(taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="173"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" mLeashByTaskId.remove(taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="175"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="192"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (taskInfo.positionInParent.equals(mPositionByTaskId.get(taskInfo.taskId))) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="211"
+ column="76"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" mPositionByTaskId.put(taskInfo.taskId, new Point(taskInfo.positionInParent));"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="218"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" mLeashByTaskId.put(taskInfo.taskId, leash);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="223"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" mPositionByTaskId.put(taskInfo.taskId, new Point(taskInfo.positionInParent));"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="224"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="231"
+ column="57"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(leash, 1f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="242"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="322"
+ column="65"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.util.SparseArray#contains`"
+ errorLine1=" if (!mLeashByTaskId.contains(taskId)) {"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="339"
+ column="29"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" b.setParent(mLeashByTaskId.get(taskId));"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="342"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (mPrimary != null) pw.println(innerPrefix + &quot;mPrimary.taskId=&quot; + mPrimary.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="351"
+ column="77"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (mSecondary != null) pw.println(innerPrefix + &quot;mSecondary.taskId=&quot; + mSecondary.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java"
+ line="352"
+ column="81"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" &amp;&amp; triggerTask.parentTaskId == mListener.mPrimary.taskId)"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java"
+ line="94"
+ column="64"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" transaction.setAlpha(leash, start * (1.f - fraction) + end * fraction);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java"
+ line="132"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" transaction.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java"
+ line="133"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" transaction.setAlpha(leash, end);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java"
+ line="136"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" transaction.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java"
+ line="137"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" transaction.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java"
+ line="180"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" transaction.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java"
+ line="185"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(parentChange.getLeash(), 1.f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java"
+ line="245"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`"
+ errorLine1=" t.reparent(leash, info.getRootLeash());"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java"
+ line="248"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(leash, info.getChanges().size() - i);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java"
+ line="249"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`"
+ errorLine1=" mFinishTransaction.reparent(leash, parentChange.getLeash());"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java"
+ line="251"
+ column="40"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(leash, info.getChanges().size() + 1);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java"
+ line="281"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(leash, 0.f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java"
+ line="294"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java"
+ line="316"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" mFinishTransaction.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java"
+ line="334"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.os.VibrationEffect#createPredefined`"
+ errorLine1=" vibrator.vibrate(VibrationEffect.createPredefined(effectId))"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/magnetictarget/MagnetizedObject.kt"
+ line="465"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Method reference requires API level 29 (current min is 26): `SurfaceControl.Transaction::new`"
+ errorLine1=" mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java"
+ line="141"
+ column="49"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" tx.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java"
+ line="286"
+ column="24"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" tx.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java"
+ line="295"
+ column="24"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Method reference requires API level 29 (current min is 26): `SurfaceControl.Transaction::new`"
+ errorLine1=" mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java"
+ line="101"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" .setParent(mParentLeash)"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java"
+ line="152"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setBufferSize`"
+ errorLine1=" .setBufferSize(mBkgBounds.width(), mBkgBounds.height())"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java"
+ line="153"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setFormat`"
+ errorLine1=" .setFormat(PixelFormat.RGB_888)"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java"
+ line="155"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setOpaque`"
+ errorLine1=" .setOpaque(true)"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java"
+ line="156"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setName`"
+ errorLine1=" .setName(&quot;one-handed-background-panel&quot;)"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java"
+ line="157"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#build`"
+ errorLine1=" .build();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java"
+ line="159"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" transaction.setLayer(mBackgroundSurface, -1 /* at bottom-most layer */)"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java"
+ line="179"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" .apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java"
+ line="182"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" transaction.remove(mBackgroundSurface).apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java"
+ line="197"
+ column="52"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.accessibility.AccessibilityManager#getRecommendedTimeoutMillis`"
+ errorLine1=" .getRecommendedTimeoutMillis(mOneHandedTimeout * 1000"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java"
+ line="150"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.os.RemoteException#rethrowFromSystemServer`"
+ errorLine1=" throw e.rethrowFromSystemServer();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java"
+ line="574"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Method reference requires API level 29 (current min is 26): `SurfaceControl.Transaction::new`"
+ errorLine1=" mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java"
+ line="130"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" tx.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java"
+ line="241"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" tx.setAlpha(leash, alpha);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSurfaceTransactionHelper.java"
+ line="57"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowManager#getCurrentWindowMetrics`"
+ errorLine1=" mDisplaySize = windowManager.getCurrentWindowMetrics().getBounds();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java"
+ line="101"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowMetrics#getBounds`"
+ errorLine1=" mDisplaySize = windowManager.getCurrentWindowMetrics().getBounds();"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java"
+ line="101"
+ column="64"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#setFitInsetsTypes`"
+ errorLine1=" lp.setFitInsetsTypes(0 /* types */);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java"
+ line="200"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Method reference requires API level 29 (current min is 26): `SurfaceControl.Transaction::new`"
+ errorLine1=" mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java"
+ line="244"
+ column="49"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" tx.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java"
+ line="399"
+ column="24"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" tx.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java"
+ line="413"
+ column="24"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" tx.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java"
+ line="499"
+ column="24"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" tx.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java"
+ line="518"
+ column="24"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" tx.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java"
+ line="532"
+ column="24"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`"
+ errorLine1=" mDefaultAspectRatio = res.getFloat("
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java"
+ line="77"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`"
+ errorLine1=" mMinAspectRatio = res.getFloat("
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java"
+ line="93"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`"
+ errorLine1=" mMaxAspectRatio = res.getFloat("
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java"
+ line="95"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`"
+ errorLine1=" mDefaultSizePercent = res.getFloat("
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java"
+ line="97"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`"
+ errorLine1=" mMaxAspectRatioForMinSize = res.getFloat("
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java"
+ line="99"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`"
+ errorLine1=" mPipBoundsState.setDisplayLayout(new DisplayLayout(mContext, mContext.getDisplay()));"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java"
+ line="337"
+ column="79"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`"
+ errorLine1=" onDisplayChanged(new DisplayLayout(mContext, mContext.getDisplay()),"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java"
+ line="428"
+ column="63"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 28 (current min is 26): `android.view.WindowManager.LayoutParams#layoutInDisplayCutoutMode`"
+ errorLine1=" lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java"
+ line="247"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#setFitInsetsTypes`"
+ errorLine1=" lp.setFitInsetsTypes(0 /* types */);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java"
+ line="248"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.accessibility.AccessibilityManager#getRecommendedTimeoutMillis`"
+ errorLine1=" int recommendedTimeout = mAccessibilityManager.getRecommendedTimeoutMillis(delay,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java"
+ line="506"
+ column="56"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`"
+ errorLine1=" mContext.getDisplay().getRealSize(mMaxSize);"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java"
+ line="142"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawX`"
+ errorLine1=" mDownPoint.set(ev.getRawX(mFirstIndex), ev.getRawY(mFirstIndex));"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java"
+ line="388"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawY`"
+ errorLine1=" mDownPoint.set(ev.getRawX(mFirstIndex), ev.getRawY(mFirstIndex));"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java"
+ line="388"
+ column="60"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawX`"
+ errorLine1=" mDownSecondPoint.set(ev.getRawX(mSecondIndex), ev.getRawY(mSecondIndex));"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java"
+ line="389"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawY`"
+ errorLine1=" mDownSecondPoint.set(ev.getRawX(mSecondIndex), ev.getRawY(mSecondIndex));"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java"
+ line="389"
+ column="67"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawX`"
+ errorLine1=" float x0 = ev.getRawX(mFirstIndex);"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java"
+ line="403"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawY`"
+ errorLine1=" float y0 = ev.getRawY(mFirstIndex);"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java"
+ line="404"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawX`"
+ errorLine1=" float x1 = ev.getRawX(mSecondIndex);"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java"
+ line="405"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawY`"
+ errorLine1=" float y1 = ev.getRawY(mSecondIndex);"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java"
+ line="406"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" tx.setAlpha(leash, alpha);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java"
+ line="66"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 31 (current min is 26): `android.graphics.Matrix#IDENTITY_MATRIX`"
+ errorLine1=" tx.setMatrix(leash, Matrix.IDENTITY_MATRIX, mTmpFloat9)"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java"
+ line="166"
+ column="29"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`"
+ errorLine1=" t.reparent(snapshot, parent);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java"
+ line="188"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(snapshot, Integer.MAX_VALUE);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java"
+ line="189"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java"
+ line="191"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Method reference requires API level 29 (current min is 26): `SurfaceControl.Transaction::new`"
+ errorLine1=" mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java"
+ line="238"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)"
+ errorLine1=" .getAnimator(mTaskInfo, mLeash, mPipBoundsState.getBounds(), 1f, 0f)"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java"
+ line="397"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)"
+ errorLine1=" mPipUiEventLoggerLogger.setTaskInfo(mTaskInfo);"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java"
+ line="431"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" tx.setAlpha(mLeash, 0f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java"
+ line="462"
+ column="16"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" tx.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java"
+ line="464"
+ column="16"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" tx.setAlpha(mLeash, 0f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java"
+ line="502"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" tx.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java"
+ line="503"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)"
+ errorLine1=" .getAnimator(mTaskInfo, mLeash, destinationBounds, 0f, 1f)"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java"
+ line="506"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" tx.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java"
+ line="820"
+ column="16"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" tx.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java"
+ line="858"
+ column="16"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" transaction.setAlpha(snapshotSurface, alpha);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java"
+ line="991"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" transaction.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java"
+ line="992"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" tx.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java"
+ line="1000"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)"
+ errorLine1=" .getAnimator(mTaskInfo, mLeash, baseBounds, currentBounds, destinationBounds,"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java"
+ line="1082"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`"
+ errorLine1=" mContext.getDisplay().getRealSize(displaySize);"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java"
+ line="380"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`"
+ errorLine1=" int displayRotation = mContext.getDisplay().getRotation();"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java"
+ line="674"
+ column="52"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawX`"
+ errorLine1=" float x = ev.getRawX(pointerIndex);"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java"
+ line="138"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawY`"
+ errorLine1=" float y = ev.getRawY(pointerIndex);"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java"
+ line="139"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawX`"
+ errorLine1=" mLastTouch.set(ev.getRawX(newPointerIndex), ev.getRawY(newPointerIndex));"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java"
+ line="174"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawY`"
+ errorLine1=" mLastTouch.set(ev.getRawX(newPointerIndex), ev.getRawY(newPointerIndex));"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java"
+ line="174"
+ column="68"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawX`"
+ errorLine1=" mLastTouch.set(ev.getRawX(pointerIndex), ev.getRawY(pointerIndex));"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java"
+ line="197"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawY`"
+ errorLine1=" mLastTouch.set(ev.getRawX(pointerIndex), ev.getRawY(pointerIndex));"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java"
+ line="197"
+ column="61"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)"
+ errorLine1=" return startEnterAnimation(change.getTaskInfo(), change.getLeash(), t);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java"
+ line="79"
+ column="44"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#topActivity`"
+ errorLine1=" setBoundsStateForEntry(taskInfo.topActivity, taskInfo.pictureInPictureParams,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java"
+ line="105"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(leash, 0f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java"
+ line="118"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java"
+ line="119"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#topActivity`"
+ errorLine1=" if (taskInfo != null &amp;&amp; taskInfo.topActivity != null) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUiEventLogger.java"
+ line="44"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#topActivity`"
+ errorLine1=" mPackageName = taskInfo.topActivity.getPackageName();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUiEventLogger.java"
+ line="45"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" b.setParent(sc);"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java"
+ line="97"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#baseIntent`"
+ errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = info.getTaskInfo().taskId; String protoLogParam1 = String.valueOf(info.getTaskInfo().baseIntent); com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, -1683614271, 1, null, protoLogParam0, protoLogParam1); "
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="168"
+ column="187"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = info.getTaskInfo().taskId; String protoLogParam1 = String.valueOf(info.getTaskInfo().baseIntent); com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, -1683614271, 1, null, protoLogParam0, protoLogParam1); "
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="168"
+ column="121"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final int taskId = info.getTaskInfo().taskId;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="333"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)"
+ errorLine1=" notifyLocusVisibilityIfNeeded(info.getTaskInfo());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="341"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = taskInfo.taskId; com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, 157713005, 1, null, protoLogParam0); }"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="348"
+ column="117"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final TaskAppearedInfo data = mTasks.get(taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="349"
+ column="54"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" mTasks.put(taskInfo.taskId, new TaskAppearedInfo(taskInfo, data.getLeash()));"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="352"
+ column="24"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)"
+ errorLine1=" notifyLocusVisibilityIfNeeded(taskInfo);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="358"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)"
+ errorLine1=" if (updated || !taskInfo.equalsForSizeCompat(data.getTaskInfo())) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="359"
+ column="58"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = taskInfo.taskId; com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, 980952660, 1, null, protoLogParam0); }"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="369"
+ column="117"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = taskInfo.taskId; com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, -880817403, 1, null, protoLogParam0); }"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="380"
+ column="117"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final int taskId = taskInfo.taskId;"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="381"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)"
+ errorLine1=" notifyLocusVisibilityIfNeeded(taskInfo);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="387"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#taskId`"
+ errorLine1=" final int taskId = taskInfo.taskId;"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="417"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#taskId`"
+ errorLine1=" mVisibleTasksWithLocusId.remove(taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="437"
+ column="49"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" mSizeCompatUI.onSizeCompatInfoChanged(taskInfo.displayId, taskInfo.taskId,"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="466"
+ column="71"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" mSizeCompatUI.onSizeCompatInfoChanged(taskInfo.displayId, taskInfo.taskId,"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="472"
+ column="67"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final int taskId = runningTaskInfo.taskId;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java"
+ line="483"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.util.SparseArray#contains`"
+ errorLine1=" } else if (mActiveLayouts.contains(taskId)) {"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIController.java"
+ line="96"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(leash, Integer.MAX_VALUE);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUILayout.java"
+ line="314"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setName`"
+ errorLine1=" .setName(&quot;SizeCompatUILeash&quot;)"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIWindowManager.java"
+ line="63"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#build`"
+ errorLine1=" mLeash = builder.build();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIWindowManager.java"
+ line="67"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" b.setParent(mLeash);"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIWindowManager.java"
+ line="68"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`"
+ errorLine1=" mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this);"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIWindowManager.java"
+ line="78"
+ column="67"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`"
+ errorLine1=" mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this);"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIWindowManager.java"
+ line="94"
+ column="67"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.SurfaceControlViewHost#release`"
+ errorLine1=" mViewHost.release();"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIWindowManager.java"
+ line="108"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" new SurfaceControl.Transaction().remove(mLeash).apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIWindowManager.java"
+ line="113"
+ column="61"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" new SurfaceControl.Transaction().remove(mLeash).apply();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIWindowManager.java"
+ line="113"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 26): `android.window.SplashScreenView#getIconView`"
+ errorLine1=" final View iconView = mSplashScreenView.getIconView();"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java"
+ line="158"
+ column="49"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.graphics.Paint#setBlendMode`"
+ errorLine1=" mVanishPaint.setBlendMode(BlendMode.MODULATE);"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java"
+ line="247"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.graphics.BlendMode#MODULATE`"
+ errorLine1=" mVanishPaint.setBlendMode(BlendMode.MODULATE);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java"
+ line="247"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" tx.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java"
+ line="284"
+ column="16"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" tx.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java"
+ line="303"
+ column="16"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#release`"
+ errorLine1=" mFirstWindowSurface.release();"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java"
+ line="304"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowManager#getMaximumWindowMetrics`"
+ errorLine1=" .getMaximumWindowMetrics()"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java"
+ line="256"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowMetrics#getWindowInsets`"
+ errorLine1=" .getWindowInsets()"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java"
+ line="257"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowInsets#getInsets`"
+ errorLine1=" .getInsets(WindowInsets.Type.navigationBars()"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java"
+ line="258"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#navigationBars`"
+ errorLine1=" .getInsets(WindowInsets.Type.navigationBars()"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java"
+ line="258"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#statusBars`"
+ errorLine1=" | WindowInsets.Type.statusBars()"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java"
+ line="259"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#displayCutout`"
+ errorLine1=" | WindowInsets.Type.displayCutout()).toRect();"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java"
+ line="260"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(parentChange.getLeash(), 1.f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java"
+ line="116"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`"
+ errorLine1=" t.reparent(leash, info.getRootLeash());"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java"
+ line="119"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(leash, info.getChanges().size() - i);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java"
+ line="120"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`"
+ errorLine1=" mFinishTransaction.reparent(leash, parentChange.getLeash());"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java"
+ line="122"
+ column="40"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(leash, 0.f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java"
+ line="158"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java"
+ line="164"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" mFinishTransaction.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java"
+ line="198"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" transaction.setAlpha(leash, start * (1.f - fraction) + end * fraction);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java"
+ line="222"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" transaction.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java"
+ line="223"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" transaction.setAlpha(leash, end);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java"
+ line="226"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" transaction.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java"
+ line="227"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" transaction.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java"
+ line="270"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" transaction.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java"
+ line="275"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setName`"
+ errorLine1=" .setName(TAG)"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java"
+ line="101"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#build`"
+ errorLine1=" mLeash = builder.build();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java"
+ line="105"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" b.setParent(mLeash);"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java"
+ line="106"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`"
+ errorLine1=" mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this);"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java"
+ line="116"
+ column="67"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.SurfaceControlViewHost#release`"
+ errorLine1=" mViewHost.release();"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java"
+ line="145"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" new SurfaceControl.Transaction().remove(mLeash).apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java"
+ line="150"
+ column="61"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" new SurfaceControl.Transaction().remove(mLeash).apply();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java"
+ line="150"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 26): `com.google.android.collect.Sets#newHashSet`"
+ errorLine1=" return Sets.newHashSet("
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java"
+ line="692"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" .setLayer(dividerLeash, Integer.MAX_VALUE)"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java"
+ line="399"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" .setLayer(dividerLeash, Integer.MAX_VALUE)"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java"
+ line="515"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" &amp;&amp; taskInfo.parentTaskId == mMainStage.mRootTaskInfo.taskId) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java"
+ line="570"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" &amp;&amp; taskInfo.parentTaskId == mSideStage.mRootTaskInfo.taskId) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java"
+ line="573"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TRANSITIONS_enabled) { long protoLogParam0 = triggerTask.taskId; String protoLogParam1 = String.valueOf(transitTypeToString(type)); long protoLogParam2 = mMainStage.getChildCount(); long protoLogParam3 = mSideStage.getChildCount(); com.android.wm.shell.protolog.ShellProtoLogImpl.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, 165317020, 81, &quot; split is active so using split&quot; + &quot;Transition to handle request. triggerTask=%d type=%s mainChildren=%d&quot; + &quot; sideChildren=%d&quot;, protoLogParam0, protoLogParam1, protoLogParam2, protoLogParam3); "
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java"
+ line="597"
+ column="120"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (!stage.containsTask(taskInfo.taskId)) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java"
+ line="655"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" + &quot; with &quot; + taskInfo.taskId + &quot; before startAnimation().&quot;);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java"
+ line="657"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (stage.containsTask(taskInfo.taskId)) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java"
+ line="660"
+ column="44"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" + &quot; with &quot; + taskInfo.taskId + &quot; before startAnimation().&quot;);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java"
+ line="662"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (!mMainStage.containsTask(mainChild.getTaskInfo().taskId)) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java"
+ line="732"
+ column="42"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" + &quot; to have been called with &quot; + mainChild.getTaskInfo().taskId"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java"
+ line="734"
+ column="58"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (!mSideStage.containsTask(sideChild.getTaskInfo().taskId)) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java"
+ line="737"
+ column="42"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" + &quot; to have been called with &quot; + sideChild.getTaskInfo().taskId"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java"
+ line="739"
+ column="58"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(leash, 1.f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java"
+ line="820"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(leash, Integer.MAX_VALUE);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java"
+ line="821"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.util.SparseArray#contains`"
+ errorLine1=" return mChildrenTaskInfo.contains(taskId);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="85"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" } else if (taskInfo.parentTaskId == mRootTaskInfo.taskId) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="96"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final int taskId = taskInfo.taskId;"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="97"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (mRootTaskInfo.taskId == taskInfo.taskId) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="116"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (mRootTaskInfo.taskId == taskInfo.taskId) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="116"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" } else if (taskInfo.parentTaskId == mRootTaskInfo.taskId) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="118"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" mChildrenTaskInfo.put(taskInfo.taskId, taskInfo);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="119"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" mCallbacks.onChildTaskStatusChanged(taskInfo.taskId, true /* present */,"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="120"
+ column="49"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" taskInfo, mChildrenLeashes.get(taskInfo.taskId), false /* firstAppeared */);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="124"
+ column="56"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final int taskId = taskInfo.taskId;"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="140"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (mRootTaskInfo.taskId == taskId) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="141"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.util.SparseArray#contains`"
+ errorLine1=" } else if (mChildrenTaskInfo.contains(taskId)) {"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="144"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (mRootTaskInfo.taskId == taskId) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="161"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" b.setParent(mRootLeash);"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="162"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.util.SparseArray#contains`"
+ errorLine1=" } else if (mChildrenLeashes.contains(taskId)) {"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="163"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" b.setParent(mChildrenLeashes.get(taskId));"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="164"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(leash, 1f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java"
+ line="194"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final int taskId = taskInfo.taskId;"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java"
+ line="131"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" + Integer.toHexString(theme) + &quot; task= &quot; + taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java"
+ line="141"
+ column="64"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast from `SplashScreenView` to `View` requires API level 31 (current min is 26)"
+ errorLine1=" win.setContentView(sView);"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java"
+ line="280"
+ column="40"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast from `SplashScreenView` to `View` requires API level 31 (current min is 26)"
+ errorLine1=" win.setContentView(sView);"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java"
+ line="284"
+ column="40"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final int taskId = startingWindowInfo.taskInfo.taskId;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java"
+ line="309"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final TaskSnapshot snapshot = getTaskSnapshot(windowInfo.taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java"
+ line="162"
+ column="63"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" Slog.d(TAG, &quot;isSnapshotCompatible no snapshot &quot; + windowInfo.taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java"
+ line="180"
+ column="71"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" mTaskLaunchingCallback.accept(runningTaskInfo.taskId, suggestionType);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java"
+ line="238"
+ column="47"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" mInFlight.onTransactionReady(mInFlight.mId, new SurfaceControl.Transaction());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java"
+ line="55"
+ column="61"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java"
+ line="114"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java"
+ line="125"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.SurfaceControlViewHost#release`"
+ errorLine1=" root.release();"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java"
+ line="121"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setName`"
+ errorLine1=" .setName(&quot;SystemWindowLeash&quot;)"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java"
+ line="278"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" .setParent(mRootSurface)"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java"
+ line="280"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#build`"
+ errorLine1=" .setCallsite(&quot;SysUiWIndowManager#attachToParentSurface&quot;).build();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java"
+ line="281"
+ column="76"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" b.setParent(leash);"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java"
+ line="285"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" new SurfaceControl.Transaction().remove(mLeashForWindow.get(token))"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java"
+ line="293"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" .apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java"
+ line="294"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final int taskId = runningTaskInfo.taskId;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="151"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 28 (current min is 26): `android.view.WindowManager.LayoutParams#layoutInDisplayCutoutMode`"
+ errorLine1=" layoutParams.layoutInDisplayCutoutMode = attrs.layoutInDisplayCutoutMode;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="186"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 28 (current min is 26): `android.view.WindowManager.LayoutParams#layoutInDisplayCutoutMode`"
+ errorLine1=" layoutParams.layoutInDisplayCutoutMode = attrs.layoutInDisplayCutoutMode;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="186"
+ column="50"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#getFitInsetsTypes`"
+ errorLine1=" layoutParams.setFitInsetsTypes(attrs.getFitInsetsTypes());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="187"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#setFitInsetsTypes`"
+ errorLine1=" layoutParams.setFitInsetsTypes(attrs.getFitInsetsTypes());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="187"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#getFitInsetsSides`"
+ errorLine1=" layoutParams.setFitInsetsSides(attrs.getFitInsetsSides());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="188"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#setFitInsetsSides`"
+ errorLine1=" layoutParams.setFitInsetsSides(attrs.getFitInsetsSides());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="188"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#isFitInsetsIgnoringVisibility`"
+ errorLine1=" layoutParams.setFitInsetsIgnoringVisibility(attrs.isFitInsetsIgnoringVisibility());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="189"
+ column="59"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#setFitInsetsIgnoringVisibility`"
+ errorLine1=" layoutParams.setFitInsetsIgnoringVisibility(attrs.isFitInsetsIgnoringVisibility());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="189"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskDescription`"
+ errorLine1=" if (runningTaskInfo.taskDescription != null) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="208"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskDescription`"
+ errorLine1=" taskDescription = runningTaskInfo.taskDescription;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="209"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" mTransaction = new SurfaceControl.Transaction();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="271"
+ column="24"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#systemBars`"
+ errorLine1=" return state.calculateInsets(frame, WindowInsets.Type.systemBars(),"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="328"
+ column="63"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setName`"
+ errorLine1=" .setName(mTitle + &quot; - task-snapshot-surface&quot;)"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="374"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setBufferSize`"
+ errorLine1=" .setBufferSize(buffer.getWidth(), buffer.getHeight())"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="375"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setFormat`"
+ errorLine1=" .setFormat(buffer.getFormat())"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="376"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" .setParent(mSurfaceControl)"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="377"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#build`"
+ errorLine1=" .build();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="379"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" mTransaction.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="406"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 26): `android.graphics.Rect#inset`"
+ errorLine1=" rect.inset((int) (insets.left * scaleX),"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java"
+ line="435"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" onTaskMovedToFront(taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java"
+ line="52"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `new android.util.CloseGuard`"
+ errorLine1=" private final CloseGuard mGuard = new CloseGuard();"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="73"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="81"
+ column="61"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.util.CloseGuard#open`"
+ errorLine1=" mGuard.open(&quot;release&quot;);"
+ errorLine2=" ~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="99"
+ column="16"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.util.CloseGuard#warnIfOpen`"
+ errorLine1=" mGuard.warnIfOpen();"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="204"
+ column="24"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.util.CloseGuard#close`"
+ errorLine1=" mGuard.close();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="218"
+ column="16"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final int taskId = mTaskInfo.taskId;"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="239"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`"
+ errorLine1=" mTransaction.reparent(mTaskLeash, getSurfaceControl())"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="255"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceView#getSurfaceControl`"
+ errorLine1=" mTransaction.reparent(mTaskLeash, getSurfaceControl())"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="255"
+ column="47"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" .apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="257"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskDescription`"
+ errorLine1=" if (taskInfo.taskDescription != null) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="266"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskDescription`"
+ errorLine1=" setResizeBackgroundColor(taskInfo.taskDescription.getBackgroundColor());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="267"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final int taskId = taskInfo.taskId;"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="271"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final int taskId = taskInfo.taskId;"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="284"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" mTransaction.reparent(mTaskLeash, null).apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="292"
+ column="49"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`"
+ errorLine1=" mTransaction.reparent(mTaskLeash, null).apply();"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="292"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskDescription`"
+ errorLine1=" if (taskInfo.taskDescription != null) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="298"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskDescription`"
+ errorLine1=" setResizeBackgroundColor(taskInfo.taskDescription.getBackgroundColor());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="299"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" final int taskId = taskInfo.taskId;"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="307"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" if (mTaskInfo.taskId != taskId) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="316"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" b.setParent(mTaskLeash);"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="319"
+ column="11"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" return &quot;TaskView&quot; + &quot;:&quot; + (mTaskInfo != null ? mTaskInfo.taskId : &quot;null&quot;);"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="331"
+ column="56"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`"
+ errorLine1=" mTransaction.reparent(mTaskLeash, getSurfaceControl())"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="349"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceView#getSurfaceControl`"
+ errorLine1=" mTransaction.reparent(mTaskLeash, getSurfaceControl())"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="349"
+ column="47"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" .apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="351"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" mTransaction.reparent(mTaskLeash, null).apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="374"
+ column="53"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`"
+ errorLine1=" mTransaction.reparent(mTaskLeash, null).apply();"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java"
+ line="374"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" return new SurfaceControl.Transaction();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/TransactionPool.java"
+ line="36"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`"
+ errorLine1=" context.getResources().getFloat("
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java"
+ line="117"
+ column="40"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#isValid`"
+ errorLine1=" if (info.getRootLeash().isValid()) {"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java"
+ line="231"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(leash, 1.f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java"
+ line="247"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`"
+ errorLine1=" t.reparent(leash, info.getRootLeash());"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java"
+ line="256"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(leash, zSplitLine + info.getChanges().size() - i);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java"
+ line="266"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(leash, 1.f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java"
+ line="270"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(leash, 0.f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java"
+ line="272"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(leash, zSplitLine - i);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java"
+ line="276"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(leash, 1.f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java"
+ line="277"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(leash, zSplitLine - i);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java"
+ line="282"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(leash, zSplitLine + info.getChanges().size() - i);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java"
+ line="285"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(leash, zSplitLine + info.getChanges().size() - i);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java"
+ line="288"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#isValid`"
+ errorLine1=" if (!info.getRootLeash().isValid()) {"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java"
+ line="304"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java"
+ line="309"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.graphics.Outline#setPath`"
+ errorLine1=" outline.setPath(mTriangularPath);"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/TriangleShape.java"
+ line="75"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`"
+ errorLine1=" mPipBoundsState.setDisplayLayout(new DisplayLayout(context, context.getDisplay()));"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java"
+ line="147"
+ column="77"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#taskId`"
+ errorLine1=" mPinnedTaskId = pinnedTask.taskId;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java"
+ line="283"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#topActivity`"
+ errorLine1=" mPipNotificationController.show(pinnedTask.topActivity.getPackageName());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java"
+ line="287"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`"
+ errorLine1=" mContext.getDisplay().getDisplayInfo(displayInfo);"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java"
+ line="348"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" SurfaceControl.Transaction t = new SurfaceControl.Transaction();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java"
+ line="134"
+ column="48"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java"
+ line="136"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#isValid`"
+ errorLine1=" if (out != null &amp;&amp; out.isValid()) {"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java"
+ line="188"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" final SurfaceControl.Transaction sft = new SurfaceControl.Transaction();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/WindowManagerProxy.java"
+ line="326"
+ column="56"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 26)"
+ errorLine1=" android:bottomLeftRadius=&quot;?android:attr/dialogCornerRadius&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/libs/WindowManager/Shell/res/drawable/rounded_bg_full.xml"
+ line="21"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 26)"
+ errorLine1=" android:topLeftRadius=&quot;?android:attr/dialogCornerRadius&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/libs/WindowManager/Shell/res/drawable/rounded_bg_full.xml"
+ line="22"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 26)"
+ errorLine1=" android:bottomRightRadius=&quot;?android:attr/dialogCornerRadius&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/libs/WindowManager/Shell/res/drawable/rounded_bg_full.xml"
+ line="23"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 26)"
+ errorLine1=" android:topRightRadius=&quot;?android:attr/dialogCornerRadius&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/libs/WindowManager/Shell/res/drawable/rounded_bg_full.xml"
+ line="24"
+ column="9"/>
+ </issue>
+
+</issues>
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 4ff1ce97ba3c..11c146457844 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
@@ -16,6 +16,7 @@
package com.android.wm.shell.bubbles;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.service.notification.NotificationListenerService.REASON_CANCEL;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
@@ -78,6 +79,8 @@ import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.TaskStackListenerCallback;
+import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.pip.PinnedStackListenerForwarder;
import java.io.FileDescriptor;
@@ -124,6 +127,7 @@ public class BubbleController {
private final LauncherApps mLauncherApps;
private final IStatusBarService mBarService;
private final WindowManager mWindowManager;
+ private final TaskStackListenerImpl mTaskStackListener;
private final ShellTaskOrganizer mTaskOrganizer;
// Used to post to main UI thread
@@ -194,6 +198,7 @@ public class BubbleController {
WindowManager windowManager,
WindowManagerShellWrapper windowManagerShellWrapper,
LauncherApps launcherApps,
+ TaskStackListenerImpl taskStackListener,
UiEventLogger uiEventLogger,
ShellTaskOrganizer organizer,
ShellExecutor mainExecutor,
@@ -204,7 +209,7 @@ public class BubbleController {
return new BubbleController(context, data, synchronizer, floatingContentCoordinator,
new BubbleDataRepository(context, launcherApps, mainExecutor),
statusBarService, windowManager, windowManagerShellWrapper, launcherApps,
- logger, organizer, positioner, mainExecutor, mainHandler);
+ logger, taskStackListener, organizer, positioner, mainExecutor, mainHandler);
}
/**
@@ -221,6 +226,7 @@ public class BubbleController {
WindowManagerShellWrapper windowManagerShellWrapper,
LauncherApps launcherApps,
BubbleLogger bubbleLogger,
+ TaskStackListenerImpl taskStackListener,
ShellTaskOrganizer organizer,
BubblePositioner positioner,
ShellExecutor mainExecutor,
@@ -238,6 +244,7 @@ public class BubbleController {
mLogger = bubbleLogger;
mMainExecutor = mainExecutor;
mMainHandler = mainHandler;
+ mTaskStackListener = taskStackListener;
mTaskOrganizer = organizer;
mSurfaceSynchronizer = synchronizer;
mCurrentUserId = ActivityManager.getCurrentUser();
@@ -319,6 +326,42 @@ public class BubbleController {
packageName, validShortcuts, DISMISS_SHORTCUT_REMOVED);
}
}, mMainHandler);
+
+ mTaskStackListener.addListener(new TaskStackListenerCallback() {
+ @Override
+ public void onTaskMovedToFront(int taskId) {
+ if (mSysuiProxy == null) {
+ return;
+ }
+
+ mSysuiProxy.isNotificationShadeExpand((expand) -> {
+ mMainExecutor.execute(() -> {
+ int expandedId = INVALID_TASK_ID;
+ if (mStackView != null && mStackView.getExpandedBubble() != null
+ && isStackExpanded() && !mStackView.isExpansionAnimating()
+ && !expand) {
+ expandedId = mStackView.getExpandedBubble().getTaskId();
+ }
+
+ if (expandedId != INVALID_TASK_ID && expandedId != taskId) {
+ mBubbleData.setExpanded(false);
+ }
+ });
+ });
+ }
+
+ @Override
+ public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
+ boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
+ for (Bubble b : mBubbleData.getBubbles()) {
+ if (task.taskId == b.getTaskId()) {
+ mBubbleData.setSelectedBubble(b);
+ mBubbleData.setExpanded(true);
+ return;
+ }
+ }
+ }
+ });
}
@VisibleForTesting
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index 9ef3fb54fb35..abe1f7179dda 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -154,6 +154,7 @@ public class BubbleExpandedView extends LinearLayout {
}
try {
options.setTaskAlwaysOnTop(true);
+ options.setLaunchedFromBubble(true);
if (!mIsOverflow && mBubble.hasMetadataShortcutId()) {
options.setApplyActivityFlagsForBubbles(true);
mTaskView.startShortcutActivity(mBubble.getShortcutInfo(),
@@ -163,7 +164,6 @@ public class BubbleExpandedView extends LinearLayout {
// Apply flags to make behaviour match documentLaunchMode=always.
fillInIntent.addFlags(FLAG_ACTIVITY_NEW_DOCUMENT);
fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
- fillInIntent.putExtra(Intent.EXTRA_IS_BUBBLED, true);
if (mBubble != null) {
mBubble.setIntentActive();
}
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 98978b562011..9fc8aef47064 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
@@ -248,6 +248,8 @@ public interface Bubbles {
/** Callback to tell SysUi components execute some methods. */
interface SysuiProxy {
+ void isNotificationShadeExpand(Consumer<Boolean> callback);
+
void getPendingOrActiveEntry(String key, Consumer<BubbleEntry> callback);
void getShouldRestoredEntries(ArraySet<String> savedBubbleKeys,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
index d25bef197359..9eacaecc4f50 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
@@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -41,8 +42,6 @@ import android.window.TaskOrganizer;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
-import androidx.annotation.Nullable;
-
import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -63,7 +62,6 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@@ -496,13 +494,15 @@ public class LegacySplitScreenController implements DisplayController.OnDisplays
public boolean splitPrimaryTask() {
try {
- if (ActivityTaskManager.getService().getLockTaskModeState() == LOCK_TASK_MODE_PINNED
- || isSplitActive()) {
+ if (ActivityTaskManager.getService().getLockTaskModeState() == LOCK_TASK_MODE_PINNED) {
return false;
}
} catch (RemoteException e) {
return false;
}
+ if (isSplitActive() || mSplits.mPrimary == null) {
+ return false;
+ }
// Try fetching the top running task.
final List<RunningTaskInfo> runningTasks =
@@ -523,8 +523,12 @@ public class LegacySplitScreenController implements DisplayController.OnDisplays
return false;
}
- return ActivityTaskManager.getInstance().setTaskWindowingModeSplitScreenPrimary(
- topRunningTask.taskId, true /* onTop */);
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ // Clear out current windowing mode before reparenting to split task.
+ wct.setWindowingMode(topRunningTask.token, WINDOWING_MODE_UNDEFINED);
+ wct.reparent(topRunningTask.token, mSplits.mPrimary.token, true /* onTop */);
+ mWindowManagerProxy.applySyncTransaction(wct);
+ return true;
}
public void dismissSplitToPrimaryTask() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl
index 0c46eaba18ae..8f0892fdcbba 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl
@@ -20,6 +20,7 @@ import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
+import android.window.IRemoteTransition;
import com.android.wm.shell.splitscreen.ISplitScreenListener;
@@ -74,4 +75,11 @@ interface ISplitScreen {
*/
oneway void startIntent(in PendingIntent intent, in Intent fillInIntent, int stage,
int position, in Bundle options) = 9;
+
+ /**
+ * Starts tasks simultaneously in one transition. The first task in the list will be in the
+ * main-stage and on the left/top.
+ */
+ oneway void startTasks(int mainTaskId, in Bundle mainOptions, int sideTaskId,
+ in Bundle sideOptions, int sidePosition, in IRemoteTransition remoteTransition) = 10;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
index 2f2e325aafad..66a4a60d4be6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
@@ -16,10 +16,7 @@
package com.android.wm.shell.splitscreen;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import android.graphics.Rect;
import android.window.WindowContainerToken;
@@ -52,6 +49,7 @@ class MainStage extends StageTaskListener {
final WindowContainerToken rootToken = mRootTaskInfo.token;
wct.setBounds(rootToken, rootBounds)
+ .setWindowingMode(rootToken, WINDOWING_MODE_MULTI_WINDOW)
.setLaunchRoot(
rootToken,
CONTROLLED_WINDOWING_MODES,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
index 340b55d7f446..d4506fd32c86 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
@@ -17,18 +17,8 @@
package com.android.wm.shell.splitscreen;
import android.annotation.IntDef;
-import android.app.ActivityManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.UserHandle;
-
-import androidx.annotation.Nullable;
import com.android.wm.shell.common.annotations.ExternalThread;
-import com.android.wm.shell.draganddrop.DragAndDropPolicy;
/**
* Interface to engage split-screen feature.
@@ -95,4 +85,14 @@ public interface SplitScreen {
default ISplitScreen createExternalInterface() {
return null;
}
+
+ /** Get a string representation of a stage type */
+ static String stageTypeToString(@StageType int stage) {
+ switch (stage) {
+ case STAGE_TYPE_UNDEFINED: return "UNDEFINED";
+ case STAGE_TYPE_MAIN: return "MAIN";
+ case STAGE_TYPE_SIDE: return "SIDE";
+ default: return "UNKNOWN(" + stage + ")";
+ }
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index d4362efe462d..5aa59f283434 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -39,6 +39,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Slog;
+import android.window.IRemoteTransition;
import androidx.annotation.BinderThread;
import androidx.annotation.NonNull;
@@ -50,9 +51,11 @@ import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.common.annotations.ExternalThread;
import com.android.wm.shell.draganddrop.DragAndDropPolicy;
import com.android.wm.shell.splitscreen.ISplitScreenListener;
+import com.android.wm.shell.transition.Transitions;
import java.io.PrintWriter;
@@ -72,19 +75,24 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
private final ShellExecutor mMainExecutor;
private final SplitScreenImpl mImpl = new SplitScreenImpl();
private final DisplayImeController mDisplayImeController;
+ private final Transitions mTransitions;
+ private final TransactionPool mTransactionPool;
private StageCoordinator mStageCoordinator;
public SplitScreenController(ShellTaskOrganizer shellTaskOrganizer,
SyncTransactionQueue syncQueue, Context context,
RootTaskDisplayAreaOrganizer rootTDAOrganizer,
- ShellExecutor mainExecutor, DisplayImeController displayImeController) {
+ ShellExecutor mainExecutor, DisplayImeController displayImeController,
+ Transitions transitions, TransactionPool transactionPool) {
mTaskOrganizer = shellTaskOrganizer;
mSyncQueue = syncQueue;
mContext = context;
mRootTDAOrganizer = rootTDAOrganizer;
mMainExecutor = mainExecutor;
mDisplayImeController = displayImeController;
+ mTransitions = transitions;
+ mTransactionPool = transactionPool;
}
public SplitScreen asSplitScreen() {
@@ -105,7 +113,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
if (mStageCoordinator == null) {
// TODO: Multi-display
mStageCoordinator = new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
- mRootTDAOrganizer, mTaskOrganizer, mDisplayImeController);
+ mRootTDAOrganizer, mTaskOrganizer, mDisplayImeController, mTransitions,
+ mTransactionPool);
}
}
@@ -407,6 +416,16 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
}
@Override
+ public void startTasks(int mainTaskId, @Nullable Bundle mainOptions,
+ int sideTaskId, @Nullable Bundle sideOptions,
+ @SplitScreen.StagePosition int sidePosition,
+ @Nullable IRemoteTransition remoteTransition) {
+ executeRemoteCallWithTaskPermission(mController, "startTasks",
+ (controller) -> controller.mStageCoordinator.startTasks(mainTaskId, mainOptions,
+ sideTaskId, sideOptions, sidePosition, remoteTransition));
+ }
+
+ @Override
public void startShortcut(String packageName, String shortcutId, int stage, int position,
@Nullable Bundle options, UserHandle user) {
executeRemoteCallWithTaskPermission(mController, "startShortcut",
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
new file mode 100644
index 000000000000..c37789ecbc9d
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
@@ -0,0 +1,296 @@
+/*
+ * 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.wm.shell.splitscreen;
+
+import static android.view.WindowManager.TRANSIT_CHANGE;
+import static android.view.WindowManager.TRANSIT_CLOSE;
+import static android.view.WindowManager.TRANSIT_OPEN;
+import static android.view.WindowManager.TRANSIT_TO_BACK;
+import static android.view.WindowManager.TRANSIT_TO_FRONT;
+import static android.window.TransitionInfo.FLAG_FIRST_CUSTOM;
+
+import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_DISMISS_SNAP;
+import static com.android.wm.shell.transition.Transitions.isOpeningType;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.graphics.Rect;
+import android.os.IBinder;
+import android.view.SurfaceControl;
+import android.view.WindowManager;
+import android.window.IRemoteTransition;
+import android.window.TransitionInfo;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
+
+import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.transition.OneShotRemoteHandler;
+import com.android.wm.shell.transition.Transitions;
+
+import java.util.ArrayList;
+
+/** Manages transition animations for split-screen. */
+class SplitScreenTransitions {
+ private static final String TAG = "SplitScreenTransitions";
+
+ /** Flag applied to a transition change to identify it as a divider bar for animation. */
+ public static final int FLAG_IS_DIVIDER_BAR = FLAG_FIRST_CUSTOM;
+
+ private final TransactionPool mTransactionPool;
+ private final Transitions mTransitions;
+ private final Runnable mOnFinish;
+
+ IBinder mPendingDismiss = null;
+ IBinder mPendingEnter = null;
+
+ private IBinder mAnimatingTransition = null;
+ private OneShotRemoteHandler mRemoteHandler = null;
+
+ private Transitions.TransitionFinishCallback mRemoteFinishCB = (wct, wctCB) -> {
+ if (wct != null || wctCB != null) {
+ throw new UnsupportedOperationException("finish transactions not supported yet.");
+ }
+ onFinish();
+ };
+
+ /** Keeps track of currently running animations */
+ private final ArrayList<Animator> mAnimations = new ArrayList<>();
+
+ private Transitions.TransitionFinishCallback mFinishCallback = null;
+ private SurfaceControl.Transaction mFinishTransaction;
+
+ SplitScreenTransitions(@NonNull TransactionPool pool, @NonNull Transitions transitions,
+ @NonNull Runnable onFinishCallback) {
+ mTransactionPool = pool;
+ mTransitions = transitions;
+ mOnFinish = onFinishCallback;
+ }
+
+ void playAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction t,
+ @NonNull Transitions.TransitionFinishCallback finishCallback,
+ @NonNull WindowContainerToken mainRoot, @NonNull WindowContainerToken sideRoot) {
+ mFinishCallback = finishCallback;
+ mAnimatingTransition = transition;
+ if (mRemoteHandler != null) {
+ mRemoteHandler.startAnimation(transition, info, t, mRemoteFinishCB);
+ mRemoteHandler = null;
+ return;
+ }
+ playInternalAnimation(transition, info, t, mainRoot, sideRoot);
+ }
+
+ private void playInternalAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction t, @NonNull WindowContainerToken mainRoot,
+ @NonNull WindowContainerToken sideRoot) {
+ mFinishTransaction = mTransactionPool.acquire();
+
+ // Play some place-holder fade animations
+ for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ final SurfaceControl leash = change.getLeash();
+ final int mode = info.getChanges().get(i).getMode();
+
+ if (mode == TRANSIT_CHANGE) {
+ if (change.getParent() != null) {
+ // This is probably reparented, so we want the parent to be immediately visible
+ final TransitionInfo.Change parentChange = info.getChange(change.getParent());
+ t.show(parentChange.getLeash());
+ t.setAlpha(parentChange.getLeash(), 1.f);
+ // and then animate this layer outside the parent (since, for example, this is
+ // the home task animating from fullscreen to part-screen).
+ t.reparent(leash, info.getRootLeash());
+ t.setLayer(leash, info.getChanges().size() - i);
+ // build the finish reparent/reposition
+ mFinishTransaction.reparent(leash, parentChange.getLeash());
+ mFinishTransaction.setPosition(leash,
+ change.getEndRelOffset().x, change.getEndRelOffset().y);
+ }
+ // TODO(shell-transitions): screenshot here
+ final Rect startBounds = new Rect(change.getStartAbsBounds());
+ if (info.getType() == TRANSIT_SPLIT_DISMISS_SNAP) {
+ // Dismissing split via snap which means the still-visible task has been
+ // dragged to its end position at animation start so reflect that here.
+ startBounds.offsetTo(change.getEndAbsBounds().left,
+ change.getEndAbsBounds().top);
+ }
+ final Rect endBounds = new Rect(change.getEndAbsBounds());
+ startBounds.offset(-info.getRootOffset().x, -info.getRootOffset().y);
+ endBounds.offset(-info.getRootOffset().x, -info.getRootOffset().y);
+ startExampleResizeAnimation(leash, startBounds, endBounds);
+ }
+ if (change.getParent() != null) {
+ continue;
+ }
+
+ if (transition == mPendingEnter && (mainRoot.equals(change.getContainer())
+ || sideRoot.equals(change.getContainer()))) {
+ t.setWindowCrop(leash, change.getStartAbsBounds().width(),
+ change.getStartAbsBounds().height());
+ }
+ boolean isOpening = isOpeningType(info.getType());
+ if (isOpening && (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT)) {
+ // fade in
+ startExampleAnimation(leash, true /* show */);
+ } else if (!isOpening && (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK)) {
+ // fade out
+ if (info.getType() == TRANSIT_SPLIT_DISMISS_SNAP) {
+ // Dismissing via snap-to-top/bottom means that the dismissed task is already
+ // not-visible (usually cropped to oblivion) so immediately set its alpha to 0
+ // and don't animate it so it doesn't pop-in when reparented.
+ t.setAlpha(leash, 0.f);
+ } else {
+ startExampleAnimation(leash, false /* show */);
+ }
+ }
+ }
+ t.apply();
+ onFinish();
+ }
+
+ /** Starts a transition to enter split with a remote transition animator. */
+ IBinder startEnterTransition(@WindowManager.TransitionType int transitType,
+ @NonNull WindowContainerTransaction wct, @Nullable IRemoteTransition remoteTransition,
+ @NonNull Transitions.TransitionHandler handler) {
+ if (remoteTransition != null) {
+ // Wrapping it for ease-of-use (OneShot handles all the binder linking/death stuff)
+ mRemoteHandler = new OneShotRemoteHandler(
+ mTransitions.getMainExecutor(), remoteTransition);
+ }
+ final IBinder transition = mTransitions.startTransition(transitType, wct, handler);
+ mPendingEnter = transition;
+ if (mRemoteHandler != null) {
+ mRemoteHandler.setTransition(transition);
+ }
+ return transition;
+ }
+
+ /** Starts a transition for dismissing split after dragging the divider to a screen edge */
+ IBinder startSnapToDismiss(@NonNull WindowContainerTransaction wct,
+ @NonNull Transitions.TransitionHandler handler) {
+ final IBinder transition = mTransitions.startTransition(
+ TRANSIT_SPLIT_DISMISS_SNAP, wct, handler);
+ mPendingDismiss = transition;
+ return transition;
+ }
+
+ void onFinish() {
+ if (!mAnimations.isEmpty()) return;
+ mOnFinish.run();
+ if (mFinishTransaction != null) {
+ mFinishTransaction.apply();
+ mTransactionPool.release(mFinishTransaction);
+ mFinishTransaction = null;
+ }
+ mFinishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
+ mFinishCallback = null;
+ if (mAnimatingTransition == mPendingEnter) {
+ mPendingEnter = null;
+ }
+ if (mAnimatingTransition == mPendingDismiss) {
+ mPendingDismiss = null;
+ }
+ mAnimatingTransition = null;
+ }
+
+ // TODO(shell-transitions): real animations
+ private void startExampleAnimation(@NonNull SurfaceControl leash, boolean show) {
+ final float end = show ? 1.f : 0.f;
+ final float start = 1.f - end;
+ final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
+ final ValueAnimator va = ValueAnimator.ofFloat(start, end);
+ va.setDuration(500);
+ va.addUpdateListener(animation -> {
+ float fraction = animation.getAnimatedFraction();
+ transaction.setAlpha(leash, start * (1.f - fraction) + end * fraction);
+ transaction.apply();
+ });
+ final Runnable finisher = () -> {
+ transaction.setAlpha(leash, end);
+ transaction.apply();
+ mTransactionPool.release(transaction);
+ mTransitions.getMainExecutor().execute(() -> {
+ mAnimations.remove(va);
+ onFinish();
+ });
+ };
+ va.addListener(new Animator.AnimatorListener() {
+ @Override
+ public void onAnimationStart(Animator animation) { }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ finisher.run();
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ finisher.run();
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) { }
+ });
+ mAnimations.add(va);
+ mTransitions.getAnimExecutor().execute(va::start);
+ }
+
+ // TODO(shell-transitions): real animations
+ private void startExampleResizeAnimation(@NonNull SurfaceControl leash,
+ @NonNull Rect startBounds, @NonNull Rect endBounds) {
+ final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
+ final ValueAnimator va = ValueAnimator.ofFloat(0.f, 1.f);
+ va.setDuration(500);
+ va.addUpdateListener(animation -> {
+ float fraction = animation.getAnimatedFraction();
+ transaction.setWindowCrop(leash,
+ (int) (startBounds.width() * (1.f - fraction) + endBounds.width() * fraction),
+ (int) (startBounds.height() * (1.f - fraction)
+ + endBounds.height() * fraction));
+ transaction.setPosition(leash,
+ startBounds.left * (1.f - fraction) + endBounds.left * fraction,
+ startBounds.top * (1.f - fraction) + endBounds.top * fraction);
+ transaction.apply();
+ });
+ final Runnable finisher = () -> {
+ transaction.setWindowCrop(leash, 0, 0);
+ transaction.setPosition(leash, endBounds.left, endBounds.top);
+ transaction.apply();
+ mTransactionPool.release(transaction);
+ mTransitions.getMainExecutor().execute(() -> {
+ mAnimations.remove(va);
+ onFinish();
+ });
+ };
+ va.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ finisher.run();
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ finisher.run();
+ }
+ });
+ mAnimations.add(va);
+ mTransitions.getAnimExecutor().execute(va::start);
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index b180bb52e3e3..c91a92ad3242 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -17,31 +17,54 @@
package com.android.wm.shell.splitscreen;
import static android.app.ActivityOptions.KEY_LAUNCH_ROOT_TASK_TOKEN;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.view.WindowManager.TRANSIT_OPEN;
+import static android.view.WindowManager.TRANSIT_TO_BACK;
+import static android.view.WindowManager.TRANSIT_TO_FRONT;
+import static android.view.WindowManager.transitTypeToString;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
-
+import static com.android.wm.shell.splitscreen.SplitScreen.stageTypeToString;
+import static com.android.wm.shell.splitscreen.SplitScreenTransitions.FLAG_IS_DIVIDER_BAR;
+import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
+import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_DISMISS_SNAP;
+import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
+import static com.android.wm.shell.transition.Transitions.isClosingType;
+import static com.android.wm.shell.transition.Transitions.isOpeningType;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
+import android.os.IBinder;
+import android.util.Log;
import android.view.SurfaceControl;
+import android.view.WindowManager;
import android.window.DisplayAreaInfo;
+import android.window.IRemoteTransition;
+import android.window.TransitionInfo;
+import android.window.TransitionRequestInfo;
import android.window.WindowContainerTransaction;
-import androidx.annotation.NonNull;
-import androidx.annotation.VisibleForTesting;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.common.split.SplitLayout;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
+import com.android.wm.shell.transition.Transitions;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -61,10 +84,13 @@ import java.util.List;
* {@link #onStageHasChildrenChanged(StageListenerImpl).}
*/
class StageCoordinator implements SplitLayout.LayoutChangeListener,
- RootTaskDisplayAreaOrganizer.RootTaskDisplayAreaListener {
+ RootTaskDisplayAreaOrganizer.RootTaskDisplayAreaListener, Transitions.TransitionHandler {
private static final String TAG = StageCoordinator.class.getSimpleName();
+ /** internal value for mDismissTop that represents no dismiss */
+ private static final int NO_DISMISS = -2;
+
private final MainStage mMainStage;
private final StageListenerImpl mMainStageListener = new StageListenerImpl();
private final SideStage mSideStage;
@@ -81,11 +107,25 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
private final Context mContext;
private final List<SplitScreen.SplitScreenListener> mListeners = new ArrayList<>();
private final DisplayImeController mDisplayImeController;
+ private final SplitScreenTransitions mSplitTransitions;
private boolean mExitSplitScreenOnHide = true;
+ @SplitScreen.StageType int mDismissTop = NO_DISMISS;
+ private final Runnable mOnTransitionAnimationComplete = () -> {
+ // If still playing, let it finish.
+ if (!isSplitScreenVisible()) {
+ // Update divider state after animation so that it is still around and positioned
+ // properly for the animation itself.
+ setDividerVisibility(false);
+ mSplitLayout.resetDividerPosition();
+ }
+ mDismissTop = NO_DISMISS;
+ };
+
StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
- DisplayImeController displayImeController) {
+ DisplayImeController displayImeController, Transitions transitions,
+ TransactionPool transactionPool) {
mContext = context;
mDisplayId = displayId;
mSyncQueue = syncQueue;
@@ -95,12 +135,16 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
mSideStage = new SideStage(mTaskOrganizer, mDisplayId, mSideStageListener, mSyncQueue);
mDisplayImeController = displayImeController;
mRootTDAOrganizer.registerListener(displayId, this);
+ mSplitTransitions = new SplitScreenTransitions(transactionPool, transitions,
+ mOnTransitionAnimationComplete);
+ transitions.addHandler(this);
}
@VisibleForTesting
StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
- MainStage mainStage, SideStage sideStage, DisplayImeController displayImeController) {
+ MainStage mainStage, SideStage sideStage, DisplayImeController displayImeController,
+ SplitLayout splitLayout, Transitions transitions, TransactionPool transactionPool) {
mContext = context;
mDisplayId = displayId;
mSyncQueue = syncQueue;
@@ -110,6 +154,15 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
mSideStage = sideStage;
mDisplayImeController = displayImeController;
mRootTDAOrganizer.registerListener(displayId, this);
+ mSplitLayout = splitLayout;
+ mSplitTransitions = new SplitScreenTransitions(transactionPool, transitions,
+ mOnTransitionAnimationComplete);
+ transitions.addHandler(this);
+ }
+
+ @VisibleForTesting
+ SplitScreenTransitions getSplitTransitions() {
+ return mSplitTransitions;
}
boolean isSplitScreenVisible() {
@@ -140,6 +193,32 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
return result;
}
+ /** Starts 2 tasks in one transition. */
+ void startTasks(int mainTaskId, @Nullable Bundle mainOptions, int sideTaskId,
+ @Nullable Bundle sideOptions, @SplitScreen.StagePosition int sidePosition,
+ @Nullable IRemoteTransition remoteTransition) {
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ mainOptions = mainOptions != null ? mainOptions : new Bundle();
+ sideOptions = sideOptions != null ? sideOptions : new Bundle();
+ setSideStagePosition(sidePosition);
+
+ // Build a request WCT that will launch both apps such that task 0 is on the main stage
+ // while task 1 is on the side stage.
+ mMainStage.activate(getMainStageBounds(), wct);
+ mSideStage.setBounds(getSideStageBounds(), wct);
+
+ // Make sure the launch options will put tasks in the corresponding split roots
+ addActivityOptions(mainOptions, mMainStage);
+ addActivityOptions(sideOptions, mSideStage);
+
+ // Add task launch requests
+ wct.startTask(mainTaskId, mainOptions);
+ wct.startTask(sideTaskId, sideOptions);
+
+ mSplitTransitions.startEnterTransition(
+ TRANSIT_SPLIT_SCREEN_PAIR_OPEN, wct, remoteTransition, this);
+ }
+
@SplitScreen.StagePosition int getSideStagePosition() {
return mSideStagePosition;
}
@@ -150,14 +229,18 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
}
void setSideStagePosition(@SplitScreen.StagePosition int sideStagePosition) {
- if (mSideStagePosition == sideStagePosition) return;
+ setSideStagePosition(sideStagePosition, true /* updateVisibility */);
+ }
+ private void setSideStagePosition(@SplitScreen.StagePosition int sideStagePosition,
+ boolean updateVisibility) {
+ if (mSideStagePosition == sideStagePosition) return;
mSideStagePosition = sideStagePosition;
- if (mSideStageListener.mVisible) {
+ sendOnStagePositionChanged();
+
+ if (mSideStageListener.mVisible && updateVisibility) {
onStageVisibilityChanged(mSideStageListener);
}
-
- sendOnStagePositionChanged();
}
void setSideStageVisibility(boolean visible) {
@@ -185,14 +268,23 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
mSplitLayout.resetDividerPosition();
}
+ private void prepareExitSplitScreen(@SplitScreen.StageType int stageToTop,
+ @NonNull WindowContainerTransaction wct) {
+ mSideStage.removeAllTasks(wct, stageToTop == STAGE_TYPE_SIDE);
+ mMainStage.deactivate(wct, stageToTop == STAGE_TYPE_MAIN);
+ }
+
void getStageBounds(Rect outTopOrLeftBounds, Rect outBottomOrRightBounds) {
outTopOrLeftBounds.set(mSplitLayout.getBounds1());
outBottomOrRightBounds.set(mSplitLayout.getBounds2());
}
- void updateActivityOptions(Bundle opts, @SplitScreen.StagePosition int position) {
- final StageTaskListener stage = position == mSideStagePosition ? mSideStage : mMainStage;
+ private void addActivityOptions(Bundle opts, StageTaskListener stage) {
opts.putParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, stage.mRootTaskInfo.token);
+ }
+
+ void updateActivityOptions(Bundle opts, @SplitScreen.StagePosition int position) {
+ addActivityOptions(opts, position == mSideStagePosition ? mSideStage : mMainStage);
if (!mMainStage.isActive()) {
// Activate the main stage in anticipation of an app launch.
@@ -258,20 +350,21 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
}
}
+ private void setDividerVisibility(boolean visible) {
+ if (mDividerVisible == visible) return;
+ mDividerVisible = visible;
+ if (visible) {
+ mSplitLayout.init();
+ } else {
+ mSplitLayout.release();
+ }
+ }
+
private void onStageVisibilityChanged(StageListenerImpl stageListener) {
final boolean sideStageVisible = mSideStageListener.mVisible;
final boolean mainStageVisible = mMainStageListener.mVisible;
// Divider is only visible if both the main stage and side stages are visible
- final boolean dividerVisible = sideStageVisible && mainStageVisible;
-
- if (mDividerVisible != dividerVisible) {
- mDividerVisible = dividerVisible;
- if (mDividerVisible) {
- mSplitLayout.init();
- } else {
- mSplitLayout.release();
- }
- }
+ setDividerVisibility(isSplitScreenVisible());
if (mExitSplitScreenOnHide && !mainStageVisible && !sideStageVisible) {
// Exit split-screen if both stage are not visible.
@@ -360,11 +453,22 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
}
}
+ @VisibleForTesting
+ IBinder onSnappedToDismissTransition(boolean mainStageToTop) {
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ prepareExitSplitScreen(mainStageToTop ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE, wct);
+ return mSplitTransitions.startSnapToDismiss(wct, this);
+ }
+
@Override
public void onSnappedToDismiss(boolean bottomOrRight) {
final boolean mainStageToTop =
bottomOrRight ? mSideStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT
: mSideStagePosition == STAGE_POSITION_TOP_OR_LEFT;
+ if (ENABLE_SHELL_TRANSITIONS) {
+ onSnappedToDismissTransition(mainStageToTop);
+ return;
+ }
exitSplitScreen(mainStageToTop ? mMainStage : mSideStage);
}
@@ -455,6 +559,271 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
? mSplitLayout.getBounds2() : mSplitLayout.getBounds1();
}
+ /**
+ * Get the stage that should contain this `taskInfo`. The stage doesn't necessarily contain
+ * this task (yet) so this can also be used to identify which stage to put a task into.
+ */
+ private StageTaskListener getStageOfTask(ActivityManager.RunningTaskInfo taskInfo) {
+ // TODO(b/184679596): Find a way to either include task-org information in the transition,
+ // or synchronize task-org callbacks so we can use stage.containsTask
+ if (mMainStage.mRootTaskInfo != null
+ && taskInfo.parentTaskId == mMainStage.mRootTaskInfo.taskId) {
+ return mMainStage;
+ } else if (mSideStage.mRootTaskInfo != null
+ && taskInfo.parentTaskId == mSideStage.mRootTaskInfo.taskId) {
+ return mSideStage;
+ }
+ return null;
+ }
+
+ @SplitScreen.StageType
+ private int getStageType(StageTaskListener stage) {
+ return stage == mMainStage ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
+ }
+
+ @Override
+ public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
+ @Nullable TransitionRequestInfo request) {
+ final ActivityManager.RunningTaskInfo triggerTask = request.getTriggerTask();
+ if (triggerTask == null) {
+ // still want to monitor everything while in split-screen, so return non-null.
+ return isSplitScreenVisible() ? new WindowContainerTransaction() : null;
+ }
+
+ WindowContainerTransaction out = null;
+ final @WindowManager.TransitionType int type = request.getType();
+ if (isSplitScreenVisible()) {
+ // try to handle everything while in split-screen, so return a WCT even if it's empty.
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " split is active so using split"
+ + "Transition to handle request. triggerTask=%d type=%s mainChildren=%d"
+ + " sideChildren=%d", triggerTask.taskId, transitTypeToString(type),
+ mMainStage.getChildCount(), mSideStage.getChildCount());
+ out = new WindowContainerTransaction();
+ final StageTaskListener stage = getStageOfTask(triggerTask);
+ if (stage != null) {
+ // dismiss split if the last task in one of the stages is going away
+ if (isClosingType(type) && stage.getChildCount() == 1) {
+ // The top should be the opposite side that is closing:
+ mDismissTop = getStageType(stage) == STAGE_TYPE_MAIN
+ ? STAGE_TYPE_SIDE : STAGE_TYPE_MAIN;
+ }
+ } else {
+ if (triggerTask.getActivityType() == ACTIVITY_TYPE_HOME && isOpeningType(type)) {
+ // Going home so dismiss both.
+ mDismissTop = STAGE_TYPE_UNDEFINED;
+ }
+ }
+ if (mDismissTop != NO_DISMISS) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " splitTransition "
+ + " deduced Dismiss from request. toTop=%s",
+ stageTypeToString(mDismissTop));
+ prepareExitSplitScreen(mDismissTop, out);
+ mSplitTransitions.mPendingDismiss = transition;
+ }
+ } else {
+ // Not in split mode, so look for an open into a split stage just so we can whine and
+ // complain about how this isn't a supported operation.
+ if ((type == TRANSIT_OPEN || type == TRANSIT_TO_FRONT)) {
+ if (getStageOfTask(triggerTask) != null) {
+ throw new IllegalStateException("Entering split implicitly with only one task"
+ + " isn't supported.");
+ }
+ }
+ }
+ return out;
+ }
+
+ @Override
+ public boolean startAnimation(@NonNull IBinder transition,
+ @NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction t,
+ @NonNull Transitions.TransitionFinishCallback finishCallback) {
+ if (transition != mSplitTransitions.mPendingDismiss
+ && transition != mSplitTransitions.mPendingEnter) {
+ // Not entering or exiting, so just do some house-keeping and validation.
+
+ // If we're not in split-mode, just abort so something else can handle it.
+ if (!isSplitScreenVisible()) return false;
+
+ for (int iC = 0; iC < info.getChanges().size(); ++iC) {
+ final TransitionInfo.Change change = info.getChanges().get(iC);
+ final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
+ if (taskInfo == null || !taskInfo.hasParentTask()) continue;
+ final StageTaskListener stage = getStageOfTask(taskInfo);
+ if (stage == null) continue;
+ if (isOpeningType(change.getMode())) {
+ if (!stage.containsTask(taskInfo.taskId)) {
+ Log.w(TAG, "Expected onTaskAppeared on " + stage + " to have been called"
+ + " with " + taskInfo.taskId + " before startAnimation().");
+ }
+ } else if (isClosingType(change.getMode())) {
+ if (stage.containsTask(taskInfo.taskId)) {
+ Log.w(TAG, "Expected onTaskVanished on " + stage + " to have been called"
+ + " with " + taskInfo.taskId + " before startAnimation().");
+ }
+ }
+ }
+ if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) {
+ // TODO(shell-transitions): Implement a fallback behavior for now.
+ throw new IllegalStateException("Somehow removed the last task in a stage"
+ + " outside of a proper transition");
+ // This can happen in some pathological cases. For example:
+ // 1. main has 2 tasks [Task A (Single-task), Task B], side has one task [Task C]
+ // 2. Task B closes itself and starts Task A in LAUNCH_ADJACENT at the same time
+ // In this case, the result *should* be that we leave split.
+ // TODO(b/184679596): Find a way to either include task-org information in
+ // the transition, or synchronize task-org callbacks.
+ }
+
+ // Use normal animations.
+ return false;
+ }
+
+ boolean shouldAnimate = true;
+ if (mSplitTransitions.mPendingEnter == transition) {
+ shouldAnimate = startPendingEnterAnimation(transition, info, t);
+ } else if (mSplitTransitions.mPendingDismiss == transition) {
+ shouldAnimate = startPendingDismissAnimation(transition, info, t);
+ }
+ if (!shouldAnimate) return false;
+
+ mSplitTransitions.playAnimation(transition, info, t, finishCallback,
+ mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token);
+ return true;
+ }
+
+ private boolean startPendingEnterAnimation(@NonNull IBinder transition,
+ @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t) {
+ if (info.getType() == TRANSIT_SPLIT_SCREEN_PAIR_OPEN) {
+ // First, verify that we actually have opened 2 apps in split.
+ TransitionInfo.Change mainChild = null;
+ TransitionInfo.Change sideChild = null;
+ for (int iC = 0; iC < info.getChanges().size(); ++iC) {
+ final TransitionInfo.Change change = info.getChanges().get(iC);
+ final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
+ if (taskInfo == null || !taskInfo.hasParentTask()) continue;
+ final @SplitScreen.StageType int stageType = getStageType(getStageOfTask(taskInfo));
+ if (stageType == STAGE_TYPE_MAIN) {
+ mainChild = change;
+ } else if (stageType == STAGE_TYPE_SIDE) {
+ sideChild = change;
+ }
+ }
+ if (mainChild == null || sideChild == null) {
+ throw new IllegalStateException("Launched 2 tasks in split, but didn't receive"
+ + " 2 tasks in transition. Possibly one of them failed to launch");
+ // TODO: fallback logic. Probably start a new transition to exit split before
+ // applying anything here. Ideally consolidate with transition-merging.
+ }
+
+ // Update local states (before animating).
+ setDividerVisibility(true);
+ setSideStagePosition(STAGE_POSITION_BOTTOM_OR_RIGHT, false /* updateVisibility */);
+ setSplitsVisible(true);
+
+ addDividerBarToTransition(info, t, true /* show */);
+
+ // Make some noise if things aren't totally expected. These states shouldn't effect
+ // transitions locally, but remotes (like Launcher) may get confused if they were
+ // depending on listener callbacks. This can happen because task-organizer callbacks
+ // aren't serialized with transition callbacks.
+ // TODO(b/184679596): Find a way to either include task-org information in
+ // the transition, or synchronize task-org callbacks.
+ if (!mMainStage.containsTask(mainChild.getTaskInfo().taskId)) {
+ Log.w(TAG, "Expected onTaskAppeared on " + mMainStage
+ + " to have been called with " + mainChild.getTaskInfo().taskId
+ + " before startAnimation().");
+ }
+ if (!mSideStage.containsTask(sideChild.getTaskInfo().taskId)) {
+ Log.w(TAG, "Expected onTaskAppeared on " + mSideStage
+ + " to have been called with " + sideChild.getTaskInfo().taskId
+ + " before startAnimation().");
+ }
+ return true;
+ } else {
+ // TODO: other entry method animations
+ throw new RuntimeException("Unsupported split-entry");
+ }
+ }
+
+ private boolean startPendingDismissAnimation(@NonNull IBinder transition,
+ @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t) {
+ // Make some noise if things aren't totally expected. These states shouldn't effect
+ // transitions locally, but remotes (like Launcher) may get confused if they were
+ // depending on listener callbacks. This can happen because task-organizer callbacks
+ // aren't serialized with transition callbacks.
+ // TODO(b/184679596): Find a way to either include task-org information in
+ // the transition, or synchronize task-org callbacks.
+ if (mMainStage.getChildCount() != 0) {
+ final StringBuilder tasksLeft = new StringBuilder();
+ for (int i = 0; i < mMainStage.getChildCount(); ++i) {
+ tasksLeft.append(i != 0 ? ", " : "");
+ tasksLeft.append(mMainStage.mChildrenTaskInfo.keyAt(i));
+ }
+ Log.w(TAG, "Expected onTaskVanished on " + mMainStage
+ + " to have been called with [" + tasksLeft.toString()
+ + "] before startAnimation().");
+ }
+ if (mSideStage.getChildCount() != 0) {
+ final StringBuilder tasksLeft = new StringBuilder();
+ for (int i = 0; i < mSideStage.getChildCount(); ++i) {
+ tasksLeft.append(i != 0 ? ", " : "");
+ tasksLeft.append(mSideStage.mChildrenTaskInfo.keyAt(i));
+ }
+ Log.w(TAG, "Expected onTaskVanished on " + mSideStage
+ + " to have been called with [" + tasksLeft.toString()
+ + "] before startAnimation().");
+ }
+
+ // Update local states.
+ setSplitsVisible(false);
+ // Wait until after animation to update divider
+
+ if (info.getType() == TRANSIT_SPLIT_DISMISS_SNAP) {
+ // Reset crops so they don't interfere with subsequent launches
+ t.setWindowCrop(mMainStage.mRootLeash, null);
+ t.setWindowCrop(mSideStage.mRootLeash, null);
+ }
+
+ if (mDismissTop == STAGE_TYPE_UNDEFINED) {
+ // Going home (dismissing both splits)
+
+ // TODO: Have a proper remote for this. Until then, though, reset state and use the
+ // normal animation stuff (which falls back to the normal launcher remote).
+ t.hide(mSplitLayout.getDividerLeash());
+ setDividerVisibility(false);
+ mSplitTransitions.mPendingDismiss = null;
+ return false;
+ }
+
+ addDividerBarToTransition(info, t, false /* show */);
+ // We're dismissing split by moving the other one to fullscreen.
+ // Since we don't have any animations for this yet, just use the internal example
+ // animations.
+ return true;
+ }
+
+ private void addDividerBarToTransition(@NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction t, boolean show) {
+ final SurfaceControl leash = mSplitLayout.getDividerLeash();
+ final TransitionInfo.Change barChange = new TransitionInfo.Change(null /* token */, leash);
+ final Rect bounds = mSplitLayout.getDividerBounds();
+ barChange.setStartAbsBounds(bounds);
+ barChange.setEndAbsBounds(bounds);
+ barChange.setMode(show ? TRANSIT_TO_FRONT : TRANSIT_TO_BACK);
+ barChange.setFlags(FLAG_IS_DIVIDER_BAR);
+ // Technically this should be order-0, but this is running after layer assignment
+ // and it's a special case, so just add to end.
+ info.addChange(barChange);
+ // Be default, make it visible. The remote animator can adjust alpha if it plans to animate.
+ if (show) {
+ t.setAlpha(leash, 1.f);
+ t.setLayer(leash, Integer.MAX_VALUE);
+ t.setPosition(leash, bounds.left, bounds.top);
+ t.show(leash);
+ }
+ }
+
@Override
public void dump(@NonNull PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
@@ -469,6 +838,16 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
pw.println(innerPrefix + "mSplitLayout=" + mSplitLayout);
}
+ /**
+ * Directly set the visibility of both splits. This assumes hasChildren matches visibility.
+ * This is intended for batch use, so it assumes other state management logic is already
+ * handled.
+ */
+ private void setSplitsVisible(boolean visible) {
+ mMainStageListener.mVisible = mSideStageListener.mVisible = visible;
+ mMainStageListener.mHasChildren = mSideStageListener.mHasChildren = visible;
+ }
+
class StageListenerImpl implements StageTaskListener.StageListenerCallbacks {
boolean mHasRootTask = false;
boolean mVisible = false;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index b8cdc4ab4d75..1da0a2d82766 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -21,6 +21,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
+
import android.annotation.CallSuper;
import android.app.ActivityManager;
import android.graphics.Point;
@@ -33,7 +35,6 @@ import androidx.annotation.NonNull;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.transition.Transitions;
import java.io.PrintWriter;
@@ -76,6 +77,14 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
taskOrganizer.createRootTask(displayId, WINDOWING_MODE_MULTI_WINDOW, this);
}
+ int getChildCount() {
+ return mChildrenTaskInfo.size();
+ }
+
+ boolean containsTask(int taskId) {
+ return mChildrenTaskInfo.contains(taskId);
+ }
+
@Override
@CallSuper
public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
@@ -83,17 +92,22 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
mRootLeash = leash;
mRootTaskInfo = taskInfo;
mCallbacks.onRootTaskAppeared();
+ sendStatusChanged();
} else if (taskInfo.parentTaskId == mRootTaskInfo.taskId) {
final int taskId = taskInfo.taskId;
mChildrenLeashes.put(taskId, leash);
mChildrenTaskInfo.put(taskId, taskInfo);
updateChildTaskSurface(taskInfo, leash, true /* firstAppeared */);
mCallbacks.onChildTaskStatusChanged(taskId, true /* present */, taskInfo.isVisible);
+ if (ENABLE_SHELL_TRANSITIONS) {
+ // Status is managed/synchronized by the transition lifecycle.
+ return;
+ }
+ sendStatusChanged();
} else {
throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
+ "\n mRootTaskInfo: " + mRootTaskInfo);
}
- sendStatusChanged();
}
@Override
@@ -103,14 +117,20 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
mRootTaskInfo = taskInfo;
} else if (taskInfo.parentTaskId == mRootTaskInfo.taskId) {
mChildrenTaskInfo.put(taskInfo.taskId, taskInfo);
- updateChildTaskSurface(
- taskInfo, mChildrenLeashes.get(taskInfo.taskId), false /* firstAppeared */);
mCallbacks.onChildTaskStatusChanged(taskInfo.taskId, true /* present */,
taskInfo.isVisible);
+ if (!ENABLE_SHELL_TRANSITIONS) {
+ updateChildTaskSurface(
+ taskInfo, mChildrenLeashes.get(taskInfo.taskId), false /* firstAppeared */);
+ }
} else {
throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
+ "\n mRootTaskInfo: " + mRootTaskInfo);
}
+ if (ENABLE_SHELL_TRANSITIONS) {
+ // Status is managed/synchronized by the transition lifecycle.
+ return;
+ }
sendStatusChanged();
}
@@ -124,8 +144,12 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
} else if (mChildrenTaskInfo.contains(taskId)) {
mChildrenTaskInfo.remove(taskId);
mChildrenLeashes.remove(taskId);
- sendStatusChanged();
mCallbacks.onChildTaskStatusChanged(taskId, false /* present */, taskInfo.isVisible);
+ if (ENABLE_SHELL_TRANSITIONS) {
+ // Status is managed/synchronized by the transition lifecycle.
+ return;
+ }
+ sendStatusChanged();
} else {
throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
+ "\n mRootTaskInfo: " + mRootTaskInfo);
@@ -166,7 +190,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
mSyncQueue.runInSync(t -> {
t.setWindowCrop(leash, null);
t.setPosition(leash, taskPositionInParent.x, taskPositionInParent.y);
- if (firstAppeared && !Transitions.ENABLE_SHELL_TRANSITIONS) {
+ if (firstAppeared && !ENABLE_SHELL_TRANSITIONS) {
t.setAlpha(leash, 1f);
t.setMatrix(leash, 1, 0, 0, 1);
t.show(leash);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index ca1b53d4d46b..64dc47f5549a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -18,6 +18,7 @@ package com.android.wm.shell.transition;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
+import static android.view.WindowManager.TRANSIT_FIRST_CUSTOM;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
@@ -70,6 +71,12 @@ public class Transitions implements RemoteCallable<Transitions> {
public static final boolean ENABLE_SHELL_TRANSITIONS =
SystemProperties.getBoolean("persist.debug.shell_transit", false);
+ /** Transition type for dismissing split-screen via dragging the divider off the screen. */
+ public static final int TRANSIT_SPLIT_DISMISS_SNAP = TRANSIT_FIRST_CUSTOM + 1;
+
+ /** Transition type for launching 2 tasks simultaneously. */
+ public static final int TRANSIT_SPLIT_SCREEN_PAIR_OPEN = TRANSIT_FIRST_CUSTOM + 2;
+
private final WindowOrganizer mOrganizer;
private final Context mContext;
private final ShellExecutor mMainExecutor;
@@ -209,6 +216,11 @@ public class Transitions implements RemoteCallable<Transitions> {
|| type == WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
}
+ /** @return true if the transition was triggered by closing something vs opening something */
+ public static boolean isClosingType(@WindowManager.TransitionType int type) {
+ return type == TRANSIT_CLOSE || type == TRANSIT_TO_BACK;
+ }
+
/**
* Reparents all participants into a shared parent and orders them based on: the global transit
* type, their transit mode, and their destination z-order.
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
index 1f58a8546796..b0de02922f74 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
@@ -17,18 +17,32 @@
package com.android.wm.shell;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import android.app.ActivityManager;
+import android.app.WindowConfiguration;
import android.graphics.Rect;
+import android.os.IBinder;
import android.window.IWindowContainerToken;
import android.window.WindowContainerToken;
public final class TestRunningTaskInfoBuilder {
static int sNextTaskId = 500;
private Rect mBounds = new Rect(0, 0, 100, 100);
- private WindowContainerToken mToken =
- new WindowContainerToken(new IWindowContainerToken.Default());
+
+ private WindowContainerToken mToken = createMockWCToken();
private int mParentTaskId = INVALID_TASK_ID;
+ private @WindowConfiguration.ActivityType int mActivityType = ACTIVITY_TYPE_STANDARD;
+
+ public static WindowContainerToken createMockWCToken() {
+ final IWindowContainerToken itoken = mock(IWindowContainerToken.class);
+ final IBinder asBinder = mock(IBinder.class);
+ doReturn(asBinder).when(itoken).asBinder();
+ return new WindowContainerToken(itoken);
+ }
public TestRunningTaskInfoBuilder setBounds(Rect bounds) {
mBounds.set(bounds);
@@ -40,12 +54,19 @@ public final class TestRunningTaskInfoBuilder {
return this;
}
+ public TestRunningTaskInfoBuilder setActivityType(
+ @WindowConfiguration.ActivityType int activityType) {
+ mActivityType = activityType;
+ return this;
+ }
+
public ActivityManager.RunningTaskInfo build() {
final ActivityManager.RunningTaskInfo info = new ActivityManager.RunningTaskInfo();
info.parentTaskId = INVALID_TASK_ID;
info.taskId = sNextTaskId++;
info.parentTaskId = mParentTaskId;
info.configuration.windowConfiguration.setBounds(mBounds);
+ info.configuration.windowConfiguration.setActivityType(mActivityType);
info.token = mToken;
info.isResizeable = true;
return info;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
new file mode 100644
index 000000000000..ab6f76996398
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
@@ -0,0 +1,80 @@
+/*
+ * 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.wm.shell.splitscreen;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.view.SurfaceControl;
+import android.window.DisplayAreaInfo;
+import android.window.IWindowContainerToken;
+import android.window.WindowContainerToken;
+
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.common.split.SplitLayout;
+import com.android.wm.shell.transition.Transitions;
+
+public class SplitTestUtils {
+
+ static SplitLayout createMockSplitLayout() {
+ final Rect dividerBounds = new Rect(48, 0, 52, 100);
+ final SurfaceControl leash = createMockSurface();
+ SplitLayout out = mock(SplitLayout.class);
+ doReturn(dividerBounds).when(out).getDividerBounds();
+ doReturn(leash).when(out).getDividerLeash();
+ return out;
+ }
+
+ static SurfaceControl createMockSurface() {
+ return createMockSurface(true);
+ }
+
+ static SurfaceControl createMockSurface(boolean valid) {
+ SurfaceControl sc = mock(SurfaceControl.class);
+ ExtendedMockito.doReturn(valid).when(sc).isValid();
+ return sc;
+ }
+
+ static class TestStageCoordinator extends StageCoordinator {
+ final DisplayAreaInfo mDisplayAreaInfo;
+
+ TestStageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
+ RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
+ MainStage mainStage, SideStage sideStage, DisplayImeController imeController,
+ SplitLayout splitLayout, Transitions transitions, TransactionPool transactionPool) {
+ super(context, displayId, syncQueue, rootTDAOrganizer, taskOrganizer, mainStage,
+ sideStage, imeController, splitLayout, transitions, transactionPool);
+
+ // Prepare default TaskDisplayArea for testing.
+ mDisplayAreaInfo = new DisplayAreaInfo(
+ new WindowContainerToken(new IWindowContainerToken.Default()),
+ DEFAULT_DISPLAY,
+ FEATURE_DEFAULT_TASK_CONTAINER);
+ this.onDisplayAreaAppeared(mDisplayAreaInfo);
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
new file mode 100644
index 000000000000..18642fcfef6c
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -0,0 +1,342 @@
+/*
+ * 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.wm.shell.splitscreen;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.TRANSIT_CHANGE;
+import static android.view.WindowManager.TRANSIT_CLOSE;
+import static android.view.WindowManager.TRANSIT_OPEN;
+import static android.view.WindowManager.TRANSIT_TO_BACK;
+import static android.view.WindowManager.TRANSIT_TO_FRONT;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT;
+
+import static com.android.wm.shell.splitscreen.SplitTestUtils.createMockSurface;
+import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import android.annotation.NonNull;
+import android.app.ActivityManager;
+import android.graphics.Rect;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.view.SurfaceControl;
+import android.window.IRemoteTransition;
+import android.window.IRemoteTransitionFinishedCallback;
+import android.window.TransitionInfo;
+import android.window.TransitionRequestInfo;
+import android.window.WindowContainerTransaction;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.TestRunningTaskInfoBuilder;
+import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.common.split.SplitLayout;
+import com.android.wm.shell.transition.Transitions;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
+
+/** Tests for {@link StageCoordinator} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SplitTransitionTests extends ShellTestCase {
+ @Mock private ShellTaskOrganizer mTaskOrganizer;
+ @Mock private SyncTransactionQueue mSyncQueue;
+ @Mock private RootTaskDisplayAreaOrganizer mRootTDAOrganizer;
+ @Mock private DisplayImeController mDisplayImeController;
+ @Mock private TransactionPool mTransactionPool;
+ @Mock private Transitions mTransitions;
+ private SplitLayout mSplitLayout;
+ private MainStage mMainStage;
+ private SideStage mSideStage;
+ private StageCoordinator mStageCoordinator;
+ private SplitScreenTransitions mSplitScreenTransitions;
+
+ private ActivityManager.RunningTaskInfo mMainChild;
+ private ActivityManager.RunningTaskInfo mSideChild;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ final ShellExecutor mockExecutor = mock(ShellExecutor.class);
+ doReturn(mockExecutor).when(mTransitions).getMainExecutor();
+ doReturn(mockExecutor).when(mTransitions).getAnimExecutor();
+ doReturn(mock(SurfaceControl.Transaction.class)).when(mTransactionPool).acquire();
+ mSplitLayout = SplitTestUtils.createMockSplitLayout();
+ mMainStage = new MainStage(mTaskOrganizer, DEFAULT_DISPLAY, mock(
+ StageTaskListener.StageListenerCallbacks.class), mSyncQueue);
+ mMainStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
+ mSideStage = new SideStage(mTaskOrganizer, DEFAULT_DISPLAY, mock(
+ StageTaskListener.StageListenerCallbacks.class), mSyncQueue);
+ mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
+ mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
+ mSyncQueue, mRootTDAOrganizer, mTaskOrganizer, mMainStage, mSideStage,
+ mDisplayImeController, mSplitLayout, mTransitions, mTransactionPool);
+ mSplitScreenTransitions = mStageCoordinator.getSplitTransitions();
+ doAnswer((Answer<IBinder>) invocation -> mock(IBinder.class))
+ .when(mTransitions).startTransition(anyInt(), any(), any());
+
+ mMainChild = new TestRunningTaskInfoBuilder()
+ .setParentTaskId(mMainStage.mRootTaskInfo.taskId).build();
+ mSideChild = new TestRunningTaskInfoBuilder()
+ .setParentTaskId(mSideStage.mRootTaskInfo.taskId).build();
+ }
+
+ @Test
+ public void testLaunchPair() {
+ TransitionInfo info = createEnterPairInfo();
+
+ TestRemoteTransition testRemote = new TestRemoteTransition();
+
+ IBinder transition = mSplitScreenTransitions.startEnterTransition(
+ TRANSIT_SPLIT_SCREEN_PAIR_OPEN, new WindowContainerTransaction(), testRemote,
+ mStageCoordinator);
+ mMainStage.onTaskAppeared(mMainChild, createMockSurface());
+ mSideStage.onTaskAppeared(mSideChild, createMockSurface());
+ boolean accepted = mStageCoordinator.startAnimation(transition, info,
+ mock(SurfaceControl.Transaction.class),
+ mock(Transitions.TransitionFinishCallback.class));
+ assertTrue(accepted);
+
+ // Make sure split-screen is now visible
+ assertTrue(mStageCoordinator.isSplitScreenVisible());
+ assertTrue(testRemote.mCalled);
+ }
+
+ @Test
+ public void testMonitorInSplit() {
+ enterSplit();
+
+ ActivityManager.RunningTaskInfo newTask = new TestRunningTaskInfoBuilder()
+ .setParentTaskId(mSideStage.mRootTaskInfo.taskId).build();
+
+ // Create a request to start a new task in side stage
+ TransitionRequestInfo request = new TransitionRequestInfo(TRANSIT_TO_FRONT, newTask, null);
+ IBinder transition = mock(IBinder.class);
+ WindowContainerTransaction result =
+ mStageCoordinator.handleRequest(transition, request);
+
+ // while in split, it should handle everything:
+ assertNotNull(result);
+
+ // Not exiting, just opening up another side-stage task.
+ assertFalse(containsSplitExit(result));
+
+ // simulate the transition
+ TransitionInfo.Change openChange = createChange(TRANSIT_TO_FRONT, newTask);
+ TransitionInfo.Change hideChange = createChange(TRANSIT_TO_BACK, mSideChild);
+
+ TransitionInfo info = new TransitionInfo(TRANSIT_TO_FRONT, 0);
+ info.addChange(openChange);
+ info.addChange(hideChange);
+ mSideStage.onTaskAppeared(newTask, createMockSurface());
+ boolean accepted = mStageCoordinator.startAnimation(transition, info,
+ mock(SurfaceControl.Transaction.class),
+ mock(Transitions.TransitionFinishCallback.class));
+ assertFalse(accepted);
+ assertTrue(mStageCoordinator.isSplitScreenVisible());
+
+ // same, but create request to close the new task
+ request = new TransitionRequestInfo(TRANSIT_CLOSE, newTask, null);
+ transition = mock(IBinder.class);
+ result = mStageCoordinator.handleRequest(transition, request);
+ assertNotNull(result);
+ assertFalse(containsSplitExit(result));
+
+ TransitionInfo.Change showChange = createChange(TRANSIT_TO_FRONT, mSideChild);
+ TransitionInfo.Change closeChange = createChange(TRANSIT_CLOSE, newTask);
+
+ info = new TransitionInfo(TRANSIT_CLOSE, 0);
+ info.addChange(showChange);
+ info.addChange(closeChange);
+ mSideStage.onTaskVanished(newTask);
+ accepted = mStageCoordinator.startAnimation(transition, info,
+ mock(SurfaceControl.Transaction.class),
+ mock(Transitions.TransitionFinishCallback.class));
+ assertFalse(accepted);
+ assertTrue(mStageCoordinator.isSplitScreenVisible());
+ }
+
+ @Test
+ public void testDismissToHome() {
+ enterSplit();
+
+ ActivityManager.RunningTaskInfo homeTask = new TestRunningTaskInfoBuilder()
+ .setActivityType(ACTIVITY_TYPE_HOME).build();
+
+ // Create a request to bring home forward
+ TransitionRequestInfo request = new TransitionRequestInfo(TRANSIT_TO_FRONT, homeTask, null);
+ IBinder transition = mock(IBinder.class);
+ WindowContainerTransaction result = mStageCoordinator.handleRequest(transition, request);
+
+ assertTrue(containsSplitExit(result));
+
+ // make sure we haven't made any local changes yet (need to wait until transition is ready)
+ assertTrue(mStageCoordinator.isSplitScreenVisible());
+
+ // simulate the transition
+ TransitionInfo.Change homeChange = createChange(TRANSIT_TO_FRONT, homeTask);
+ TransitionInfo.Change mainChange = createChange(TRANSIT_TO_BACK, mMainChild);
+ TransitionInfo.Change sideChange = createChange(TRANSIT_TO_BACK, mSideChild);
+
+ TransitionInfo info = new TransitionInfo(TRANSIT_TO_FRONT, 0);
+ info.addChange(homeChange);
+ info.addChange(mainChange);
+ info.addChange(sideChange);
+ mMainStage.onTaskVanished(mMainChild);
+ mSideStage.onTaskVanished(mSideChild);
+ mStageCoordinator.startAnimation(transition, info,
+ mock(SurfaceControl.Transaction.class),
+ mock(Transitions.TransitionFinishCallback.class));
+ assertFalse(mStageCoordinator.isSplitScreenVisible());
+ }
+
+ @Test
+ public void testDismissSnap() {
+ enterSplit();
+
+ // simulate the transition
+ TransitionInfo.Change mainChange = createChange(TRANSIT_TO_BACK, mMainChild);
+ TransitionInfo.Change sideChange = createChange(TRANSIT_CHANGE, mSideChild);
+
+ TransitionInfo info = new TransitionInfo(TRANSIT_TO_BACK, 0);
+ info.addChange(mainChange);
+ info.addChange(sideChange);
+ IBinder transition = mStageCoordinator.onSnappedToDismissTransition(
+ false /* mainStageToTop */);
+ mMainStage.onTaskVanished(mMainChild);
+ mSideStage.onTaskVanished(mSideChild);
+ boolean accepted = mStageCoordinator.startAnimation(transition, info,
+ mock(SurfaceControl.Transaction.class),
+ mock(Transitions.TransitionFinishCallback.class));
+ assertTrue(accepted);
+ assertFalse(mStageCoordinator.isSplitScreenVisible());
+ }
+
+ @Test
+ public void testDismissFromAppFinish() {
+ enterSplit();
+
+ // Create a request to exit the "last" task on side stage
+ TransitionRequestInfo request = new TransitionRequestInfo(TRANSIT_CLOSE, mSideChild, null);
+ IBinder transition = mock(IBinder.class);
+ WindowContainerTransaction result = mStageCoordinator.handleRequest(transition, request);
+
+ assertTrue(containsSplitExit(result));
+
+ // make sure we haven't made any local changes yet (need to wait until transition is ready)
+ assertTrue(mStageCoordinator.isSplitScreenVisible());
+
+ // simulate the transition
+ TransitionInfo.Change mainChange = createChange(TRANSIT_CHANGE, mMainChild);
+ TransitionInfo.Change sideChange = createChange(TRANSIT_CLOSE, mSideChild);
+
+ TransitionInfo info = new TransitionInfo(TRANSIT_CLOSE, 0);
+ info.addChange(mainChange);
+ info.addChange(sideChange);
+ mMainStage.onTaskVanished(mMainChild);
+ mSideStage.onTaskVanished(mSideChild);
+ boolean accepted = mStageCoordinator.startAnimation(transition, info,
+ mock(SurfaceControl.Transaction.class),
+ mock(Transitions.TransitionFinishCallback.class));
+ assertTrue(accepted);
+ assertFalse(mStageCoordinator.isSplitScreenVisible());
+ }
+
+ private TransitionInfo createEnterPairInfo() {
+ TransitionInfo.Change mainChange = createChange(TRANSIT_OPEN, mMainChild);
+ TransitionInfo.Change sideChange = createChange(TRANSIT_OPEN, mSideChild);
+
+ TransitionInfo info = new TransitionInfo(TRANSIT_SPLIT_SCREEN_PAIR_OPEN, 0);
+ info.addChange(mainChange);
+ info.addChange(sideChange);
+ return info;
+ }
+
+ private void enterSplit() {
+ TransitionInfo enterInfo = createEnterPairInfo();
+ IBinder enterTransit = mSplitScreenTransitions.startEnterTransition(
+ TRANSIT_SPLIT_SCREEN_PAIR_OPEN, new WindowContainerTransaction(),
+ new TestRemoteTransition(), mStageCoordinator);
+ mMainStage.onTaskAppeared(mMainChild, createMockSurface());
+ mSideStage.onTaskAppeared(mSideChild, createMockSurface());
+ mStageCoordinator.startAnimation(enterTransit, enterInfo,
+ mock(SurfaceControl.Transaction.class),
+ mock(Transitions.TransitionFinishCallback.class));
+ mMainStage.activate(new Rect(0, 0, 100, 100), new WindowContainerTransaction());
+ }
+
+ private boolean containsSplitExit(@NonNull WindowContainerTransaction wct) {
+ // reparenting of child tasks to null constitutes exiting split.
+ boolean reparentedMain = false;
+ boolean reparentedSide = false;
+ for (int i = 0; i < wct.getHierarchyOps().size(); ++i) {
+ WindowContainerTransaction.HierarchyOp op = wct.getHierarchyOps().get(i);
+ if (op.getType() == HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT) {
+ if (op.getContainer() == mMainStage.mRootTaskInfo.token.asBinder()
+ && op.getNewParent() == null) {
+ reparentedMain = true;
+ } else if (op.getContainer() == mSideStage.mRootTaskInfo.token.asBinder()
+ && op.getNewParent() == null) {
+ reparentedSide = true;
+ }
+ }
+ }
+ return reparentedMain && reparentedSide;
+ }
+
+ private static TransitionInfo.Change createChange(@TransitionInfo.TransitionMode int mode,
+ ActivityManager.RunningTaskInfo taskInfo) {
+ TransitionInfo.Change out = new TransitionInfo.Change(taskInfo.token, createMockSurface());
+ out.setMode(mode);
+ out.setTaskInfo(taskInfo);
+ return out;
+ }
+
+ class TestRemoteTransition extends IRemoteTransition.Stub {
+ boolean mCalled = false;
+ final WindowContainerTransaction mRemoteFinishWCT = new WindowContainerTransaction();
+
+ @Override
+ public void startAnimation(TransitionInfo info, SurfaceControl.Transaction t,
+ IRemoteTransitionFinishedCallback finishCallback) throws RemoteException {
+ mCalled = true;
+ finishCallback.onTransitionFinished(mRemoteFinishWCT);
+ }
+ }
+
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index 74753aac4a24..924e94679831 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -17,7 +17,6 @@
package com.android.wm.shell.splitscreen;
import static android.view.Display.DEFAULT_DISPLAY;
-import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_POSITION_BOTTOM_OR_RIGHT;
@@ -27,11 +26,7 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import android.app.ActivityManager;
-import android.content.Context;
import android.graphics.Rect;
-import android.window.DisplayAreaInfo;
-import android.window.IWindowContainerToken;
-import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -43,6 +38,8 @@ import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.transition.Transitions;
import org.junit.Before;
import org.junit.Test;
@@ -60,13 +57,16 @@ public class StageCoordinatorTests extends ShellTestCase {
@Mock private MainStage mMainStage;
@Mock private SideStage mSideStage;
@Mock private DisplayImeController mDisplayImeController;
+ @Mock private Transitions mTransitions;
+ @Mock private TransactionPool mTransactionPool;
private StageCoordinator mStageCoordinator;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- mStageCoordinator = new TestStageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
- mRootTDAOrganizer, mTaskOrganizer, mMainStage, mSideStage, mDisplayImeController);
+ mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
+ mSyncQueue, mRootTDAOrganizer, mTaskOrganizer, mMainStage, mSideStage,
+ mDisplayImeController, null /* splitLayout */, mTransitions, mTransactionPool);
}
@Test
@@ -90,22 +90,4 @@ public class StageCoordinatorTests extends ShellTestCase {
verify(mSideStage).removeTask(
eq(task.taskId), any(), any(WindowContainerTransaction.class));
}
-
- private static class TestStageCoordinator extends StageCoordinator {
- final DisplayAreaInfo mDisplayAreaInfo;
-
- TestStageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
- RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
- MainStage mainStage, SideStage sideStage, DisplayImeController imeController) {
- super(context, displayId, syncQueue, rootTDAOrganizer, taskOrganizer, mainStage,
- sideStage, imeController);
-
- // Prepare default TaskDisplayArea for testing.
- mDisplayAreaInfo = new DisplayAreaInfo(
- new WindowContainerToken(new IWindowContainerToken.Default()),
- DEFAULT_DISPLAY,
- FEATURE_DEFAULT_TASK_CONTAINER);
- this.onDisplayAreaAppeared(mDisplayAreaInfo);
- }
- }
}
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index c75b21f739cd..9270901bcacd 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -503,6 +503,7 @@ cc_defaults {
"RenderProperties.cpp",
"RootRenderNode.cpp",
"SkiaCanvas.cpp",
+ "SkiaInterpolator.cpp",
"VectorDrawable.cpp",
],
diff --git a/libs/hwui/FrameInfo.cpp b/libs/hwui/FrameInfo.cpp
index 2448cc904104..51fbf363f51c 100644
--- a/libs/hwui/FrameInfo.cpp
+++ b/libs/hwui/FrameInfo.cpp
@@ -21,29 +21,16 @@ namespace android {
namespace uirenderer {
const std::array FrameInfoNames{
- "Flags",
- "FrameTimelineVsyncId",
- "IntendedVsync",
- "Vsync",
- "InputEventId",
- "HandleInputStart",
- "AnimationStart",
- "PerformTraversalsStart",
- "DrawStart",
- "FrameDeadline",
- "SyncQueued",
- "SyncStart",
- "IssueDrawCommandsStart",
- "SwapBuffers",
- "FrameCompleted",
- "DequeueBufferDuration",
- "QueueBufferDuration",
- "GpuCompleted",
- "SwapBuffersCompleted",
- "DisplayPresentTime",
+ "Flags", "FrameTimelineVsyncId", "IntendedVsync",
+ "Vsync", "InputEventId", "HandleInputStart",
+ "AnimationStart", "PerformTraversalsStart", "DrawStart",
+ "FrameDeadline", "FrameStartTime", "SyncQueued",
+ "SyncStart", "IssueDrawCommandsStart", "SwapBuffers",
+ "FrameCompleted", "DequeueBufferDuration", "QueueBufferDuration",
+ "GpuCompleted", "SwapBuffersCompleted", "DisplayPresentTime",
};
-static_assert(static_cast<int>(FrameInfoIndex::NumIndexes) == 20,
+static_assert(static_cast<int>(FrameInfoIndex::NumIndexes) == 21,
"Must update value in FrameMetrics.java#FRAME_STATS_COUNT (and here)");
void FrameInfo::importUiThreadInfo(int64_t* info) {
diff --git a/libs/hwui/FrameInfo.h b/libs/hwui/FrameInfo.h
index e9b2f4a9bb3b..62ac4ca5fdad 100644
--- a/libs/hwui/FrameInfo.h
+++ b/libs/hwui/FrameInfo.h
@@ -28,7 +28,7 @@
namespace android {
namespace uirenderer {
-static constexpr size_t UI_THREAD_FRAME_INFO_SIZE = 10;
+static constexpr size_t UI_THREAD_FRAME_INFO_SIZE = 11;
enum class FrameInfoIndex {
Flags = 0,
@@ -41,6 +41,7 @@ enum class FrameInfoIndex {
PerformTraversalsStart,
DrawStart,
FrameDeadline,
+ FrameStartTime,
// End of UI frame info
SyncQueued,
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index e58f31fd15eb..7af0a221d228 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -81,6 +81,9 @@ bool Properties::isolatedProcess = false;
int Properties::contextPriority = 0;
float Properties::defaultSdrWhitePoint = 200.f;
+bool Properties::useHintManager = true;
+int Properties::targetCpuTimePercentage = 70;
+
bool Properties::load() {
bool prevDebugLayersUpdates = debugLayersUpdates;
bool prevDebugOverdraw = debugOverdraw;
@@ -128,6 +131,10 @@ bool Properties::load() {
runningInEmulator = base::GetBoolProperty(PROPERTY_IS_EMULATOR, false);
+ useHintManager = base::GetBoolProperty(PROPERTY_USE_HINT_MANAGER, true);
+ targetCpuTimePercentage = base::GetIntProperty(PROPERTY_TARGET_CPU_TIME_PERCENTAGE, 70);
+ if (targetCpuTimePercentage <= 0 || targetCpuTimePercentage > 100) targetCpuTimePercentage = 70;
+
return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw);
}
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index ea9cbd592d29..1cb87be98051 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -158,6 +158,20 @@ enum DebugLevel {
#define PROPERTY_CAPTURE_SKP_FILENAME "debug.hwui.skp_filename"
/**
+ * Controls whether HWUI will send timing hints to HintManager for
+ * better CPU scheduling. Accepted values are "true" and "false".
+ */
+#define PROPERTY_USE_HINT_MANAGER "debug.hwui.use_hint_manager"
+
+/**
+ * Percentage of frame time that's used for CPU work. The rest is
+ * reserved for GPU work. This is used with use_hint_manager to
+ * provide timing hints to HintManager. Accepted values are
+ * integer from 1-100.
+ */
+#define PROPERTY_TARGET_CPU_TIME_PERCENTAGE "debug.hwui.target_cpu_time_percent"
+
+/**
* Property for whether this is running in the emulator.
*/
#define PROPERTY_IS_EMULATOR "ro.boot.qemu"
@@ -253,6 +267,9 @@ public:
static float defaultSdrWhitePoint;
+ static bool useHintManager;
+ static int targetCpuTimePercentage;
+
private:
static ProfileType sProfileType;
static bool sDisableProfileBars;
diff --git a/libs/hwui/SkiaInterpolator.cpp b/libs/hwui/SkiaInterpolator.cpp
new file mode 100644
index 000000000000..0695dd1ab218
--- /dev/null
+++ b/libs/hwui/SkiaInterpolator.cpp
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2008 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 "SkiaInterpolator.h"
+
+#include "include/core/SkMath.h"
+#include "include/private/SkFixed.h"
+#include "include/private/SkMalloc.h"
+#include "include/private/SkTo.h"
+#include "src/core/SkTSearch.h"
+
+typedef int Dot14;
+#define Dot14_ONE (1 << 14)
+#define Dot14_HALF (1 << 13)
+
+#define Dot14ToFloat(x) ((x) / 16384.f)
+
+static inline Dot14 Dot14Mul(Dot14 a, Dot14 b) {
+ return (a * b + Dot14_HALF) >> 14;
+}
+
+static inline Dot14 eval_cubic(Dot14 t, Dot14 A, Dot14 B, Dot14 C) {
+ return Dot14Mul(Dot14Mul(Dot14Mul(C, t) + B, t) + A, t);
+}
+
+static inline Dot14 pin_and_convert(float x) {
+ if (x <= 0) {
+ return 0;
+ }
+ if (x >= SK_Scalar1) {
+ return Dot14_ONE;
+ }
+ return SkScalarToFixed(x) >> 2;
+}
+
+static float SkUnitCubicInterp(float value, float bx, float by, float cx, float cy) {
+ // pin to the unit-square, and convert to 2.14
+ Dot14 x = pin_and_convert(value);
+
+ if (x == 0) return 0;
+ if (x == Dot14_ONE) return SK_Scalar1;
+
+ Dot14 b = pin_and_convert(bx);
+ Dot14 c = pin_and_convert(cx);
+
+ // Now compute our coefficients from the control points
+ // t -> 3b
+ // t^2 -> 3c - 6b
+ // t^3 -> 3b - 3c + 1
+ Dot14 A = 3 * b;
+ Dot14 B = 3 * (c - 2 * b);
+ Dot14 C = 3 * (b - c) + Dot14_ONE;
+
+ // Now search for a t value given x
+ Dot14 t = Dot14_HALF;
+ Dot14 dt = Dot14_HALF;
+ for (int i = 0; i < 13; i++) {
+ dt >>= 1;
+ Dot14 guess = eval_cubic(t, A, B, C);
+ if (x < guess) {
+ t -= dt;
+ } else {
+ t += dt;
+ }
+ }
+
+ // Now we have t, so compute the coeff for Y and evaluate
+ b = pin_and_convert(by);
+ c = pin_and_convert(cy);
+ A = 3 * b;
+ B = 3 * (c - 2 * b);
+ C = 3 * (b - c) + Dot14_ONE;
+ return SkFixedToScalar(eval_cubic(t, A, B, C) << 2);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+SkiaInterpolatorBase::SkiaInterpolatorBase() {
+ fStorage = nullptr;
+ fTimes = nullptr;
+ SkDEBUGCODE(fTimesArray = nullptr;)
+}
+
+SkiaInterpolatorBase::~SkiaInterpolatorBase() {
+ if (fStorage) {
+ sk_free(fStorage);
+ }
+}
+
+void SkiaInterpolatorBase::reset(int elemCount, int frameCount) {
+ fFlags = 0;
+ fElemCount = SkToU8(elemCount);
+ fFrameCount = SkToS16(frameCount);
+ fRepeat = SK_Scalar1;
+ if (fStorage) {
+ sk_free(fStorage);
+ fStorage = nullptr;
+ fTimes = nullptr;
+ SkDEBUGCODE(fTimesArray = nullptr);
+ }
+}
+
+/* Each value[] run is formatted as:
+ <time (in msec)>
+ <blend>
+ <data[fElemCount]>
+
+ Totaling fElemCount+2 entries per keyframe
+*/
+
+bool SkiaInterpolatorBase::getDuration(SkMSec* startTime, SkMSec* endTime) const {
+ if (fFrameCount == 0) {
+ return false;
+ }
+
+ if (startTime) {
+ *startTime = fTimes[0].fTime;
+ }
+ if (endTime) {
+ *endTime = fTimes[fFrameCount - 1].fTime;
+ }
+ return true;
+}
+
+float SkiaInterpolatorBase::ComputeRelativeT(SkMSec time, SkMSec prevTime, SkMSec nextTime,
+ const float blend[4]) {
+ SkASSERT(time > prevTime && time < nextTime);
+
+ float t = (float)(time - prevTime) / (float)(nextTime - prevTime);
+ return blend ? SkUnitCubicInterp(t, blend[0], blend[1], blend[2], blend[3]) : t;
+}
+
+SkiaInterpolatorBase::Result SkiaInterpolatorBase::timeToT(SkMSec time, float* T, int* indexPtr,
+ bool* exactPtr) const {
+ SkASSERT(fFrameCount > 0);
+ Result result = kNormal_Result;
+ if (fRepeat != SK_Scalar1) {
+ SkMSec startTime = 0, endTime = 0; // initialize to avoid warning
+ this->getDuration(&startTime, &endTime);
+ SkMSec totalTime = endTime - startTime;
+ SkMSec offsetTime = time - startTime;
+ endTime = SkScalarFloorToInt(fRepeat * totalTime);
+ if (offsetTime >= endTime) {
+ float fraction = SkScalarFraction(fRepeat);
+ offsetTime = fraction == 0 && fRepeat > 0
+ ? totalTime
+ : (SkMSec)SkScalarFloorToInt(fraction * totalTime);
+ result = kFreezeEnd_Result;
+ } else {
+ int mirror = fFlags & kMirror;
+ offsetTime = offsetTime % (totalTime << mirror);
+ if (offsetTime > totalTime) { // can only be true if fMirror is true
+ offsetTime = (totalTime << 1) - offsetTime;
+ }
+ }
+ time = offsetTime + startTime;
+ }
+
+ int index = SkTSearch<SkMSec>(&fTimes[0].fTime, fFrameCount, time, sizeof(SkTimeCode));
+
+ bool exact = true;
+
+ if (index < 0) {
+ index = ~index;
+ if (index == 0) {
+ result = kFreezeStart_Result;
+ } else if (index == fFrameCount) {
+ if (fFlags & kReset) {
+ index = 0;
+ } else {
+ index -= 1;
+ }
+ result = kFreezeEnd_Result;
+ } else {
+ exact = false;
+ }
+ }
+ SkASSERT(index < fFrameCount);
+ const SkTimeCode* nextTime = &fTimes[index];
+ SkMSec nextT = nextTime[0].fTime;
+ if (exact) {
+ *T = 0;
+ } else {
+ SkMSec prevT = nextTime[-1].fTime;
+ *T = ComputeRelativeT(time, prevT, nextT, nextTime[-1].fBlend);
+ }
+ *indexPtr = index;
+ *exactPtr = exact;
+ return result;
+}
+
+SkiaInterpolator::SkiaInterpolator() {
+ INHERITED::reset(0, 0);
+ fValues = nullptr;
+ SkDEBUGCODE(fScalarsArray = nullptr;)
+}
+
+SkiaInterpolator::SkiaInterpolator(int elemCount, int frameCount) {
+ SkASSERT(elemCount > 0);
+ this->reset(elemCount, frameCount);
+}
+
+void SkiaInterpolator::reset(int elemCount, int frameCount) {
+ INHERITED::reset(elemCount, frameCount);
+ fStorage = sk_malloc_throw((sizeof(float) * elemCount + sizeof(SkTimeCode)) * frameCount);
+ fTimes = (SkTimeCode*)fStorage;
+ fValues = (float*)((char*)fStorage + sizeof(SkTimeCode) * frameCount);
+#ifdef SK_DEBUG
+ fTimesArray = (SkTimeCode(*)[10])fTimes;
+ fScalarsArray = (float(*)[10])fValues;
+#endif
+}
+
+#define SK_Fixed1Third (SK_Fixed1 / 3)
+#define SK_Fixed2Third (SK_Fixed1 * 2 / 3)
+
+static const float gIdentityBlend[4] = {0.33333333f, 0.33333333f, 0.66666667f, 0.66666667f};
+
+bool SkiaInterpolator::setKeyFrame(int index, SkMSec time, const float values[],
+ const float blend[4]) {
+ SkASSERT(values != nullptr);
+
+ if (blend == nullptr) {
+ blend = gIdentityBlend;
+ }
+
+ bool success = ~index == SkTSearch<SkMSec>(&fTimes->fTime, index, time, sizeof(SkTimeCode));
+ SkASSERT(success);
+ if (success) {
+ SkTimeCode* timeCode = &fTimes[index];
+ timeCode->fTime = time;
+ memcpy(timeCode->fBlend, blend, sizeof(timeCode->fBlend));
+ float* dst = &fValues[fElemCount * index];
+ memcpy(dst, values, fElemCount * sizeof(float));
+ }
+ return success;
+}
+
+SkiaInterpolator::Result SkiaInterpolator::timeToValues(SkMSec time, float values[]) const {
+ float T;
+ int index;
+ bool exact;
+ Result result = timeToT(time, &T, &index, &exact);
+ if (values) {
+ const float* nextSrc = &fValues[index * fElemCount];
+
+ if (exact) {
+ memcpy(values, nextSrc, fElemCount * sizeof(float));
+ } else {
+ SkASSERT(index > 0);
+
+ const float* prevSrc = nextSrc - fElemCount;
+
+ for (int i = fElemCount - 1; i >= 0; --i) {
+ values[i] = SkScalarInterp(prevSrc[i], nextSrc[i], T);
+ }
+ }
+ }
+ return result;
+}
diff --git a/libs/hwui/SkiaInterpolator.h b/libs/hwui/SkiaInterpolator.h
new file mode 100644
index 000000000000..c03f502528be
--- /dev/null
+++ b/libs/hwui/SkiaInterpolator.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2006 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.
+ */
+
+#ifndef SkiaInterpolator_DEFINED
+#define SkiaInterpolator_DEFINED
+
+#include "include/private/SkTo.h"
+
+class SkiaInterpolatorBase {
+public:
+ enum Result { kNormal_Result, kFreezeStart_Result, kFreezeEnd_Result };
+
+protected:
+ SkiaInterpolatorBase();
+ ~SkiaInterpolatorBase();
+
+public:
+ void reset(int elemCount, int frameCount);
+
+ /** Return the start and end time for this interpolator.
+ If there are no key frames, return false.
+ @param startTime If not null, returns the time (in milliseconds) of the
+ first keyframe. If there are no keyframes, this param
+ is ignored (left unchanged).
+ @param endTime If not null, returns the time (in milliseconds) of the
+ last keyframe. If there are no keyframes, this parameter
+ is ignored (left unchanged).
+ @return True if there are key frames, or false if there are none.
+ */
+ bool getDuration(uint32_t* startTime, uint32_t* endTime) const;
+
+ /** Set the whether the repeat is mirrored.
+ @param mirror If true, the odd repeats interpolate from the last key
+ frame and the first.
+ */
+ void setMirror(bool mirror) { fFlags = SkToU8((fFlags & ~kMirror) | (int)mirror); }
+
+ /** Set the repeat count. The repeat count may be fractional.
+ @param repeatCount Multiplies the total time by this scalar.
+ */
+ void setRepeatCount(float repeatCount) { fRepeat = repeatCount; }
+
+ /** Set the whether the repeat is mirrored.
+ @param reset If true, the odd repeats interpolate from the last key
+ frame and the first.
+ */
+ void setReset(bool reset) { fFlags = SkToU8((fFlags & ~kReset) | (int)reset); }
+
+ Result timeToT(uint32_t time, float* T, int* index, bool* exact) const;
+
+protected:
+ enum Flags { kMirror = 1, kReset = 2, kHasBlend = 4 };
+ static float ComputeRelativeT(uint32_t time, uint32_t prevTime, uint32_t nextTime,
+ const float blend[4] = nullptr);
+ int16_t fFrameCount;
+ uint8_t fElemCount;
+ uint8_t fFlags;
+ float fRepeat;
+ struct SkTimeCode {
+ uint32_t fTime;
+ float fBlend[4];
+ };
+ SkTimeCode* fTimes; // pointer into fStorage
+ void* fStorage;
+#ifdef SK_DEBUG
+ SkTimeCode (*fTimesArray)[10];
+#endif
+};
+
+class SkiaInterpolator : public SkiaInterpolatorBase {
+public:
+ SkiaInterpolator();
+ SkiaInterpolator(int elemCount, int frameCount);
+
+ void reset(int elemCount, int frameCount);
+
+ /** Add or replace a key frame, copying the values[] data into the
+ interpolator.
+ @param index The index of this frame (frames must be ordered by time)
+ @param time The millisecond time for this frame
+ @param values The array of values [elemCount] for this frame. The data
+ is copied into the interpolator.
+ @param blend A positive scalar specifying how to blend between this
+ and the next key frame. [0...1) is a cubic lag/log/lag
+ blend (slow to change at the beginning and end)
+ 1 is a linear blend (default)
+ */
+ bool setKeyFrame(int index, uint32_t time, const float values[],
+ const float blend[4] = nullptr);
+
+ /** Return the computed values given the specified time. Return whether
+ those values are the result of pinning to either the first
+ (kFreezeStart) or last (kFreezeEnd), or from interpolated the two
+ nearest key values (kNormal).
+ @param time The time to sample (in milliseconds)
+ @param (may be null) where to write the computed values.
+ */
+ Result timeToValues(uint32_t time, float values[] = nullptr) const;
+
+private:
+ float* fValues; // pointer into fStorage
+
+ using INHERITED = SkiaInterpolatorBase;
+};
+
+#endif
diff --git a/libs/hwui/jni/Interpolator.cpp b/libs/hwui/jni/Interpolator.cpp
index 146d634a297c..fc3d70b87f5a 100644
--- a/libs/hwui/jni/Interpolator.cpp
+++ b/libs/hwui/jni/Interpolator.cpp
@@ -1,26 +1,26 @@
#include "GraphicsJNI.h"
-#include "SkInterpolator.h"
+#include "SkiaInterpolator.h"
static jlong Interpolator_constructor(JNIEnv* env, jobject clazz, jint valueCount, jint frameCount)
{
- return reinterpret_cast<jlong>(new SkInterpolator(valueCount, frameCount));
+ return reinterpret_cast<jlong>(new SkiaInterpolator(valueCount, frameCount));
}
static void Interpolator_destructor(JNIEnv* env, jobject clazz, jlong interpHandle)
{
- SkInterpolator* interp = reinterpret_cast<SkInterpolator*>(interpHandle);
+ SkiaInterpolator* interp = reinterpret_cast<SkiaInterpolator*>(interpHandle);
delete interp;
}
static void Interpolator_reset(JNIEnv* env, jobject clazz, jlong interpHandle, jint valueCount, jint frameCount)
{
- SkInterpolator* interp = reinterpret_cast<SkInterpolator*>(interpHandle);
+ SkiaInterpolator* interp = reinterpret_cast<SkiaInterpolator*>(interpHandle);
interp->reset(valueCount, frameCount);
}
static void Interpolator_setKeyFrame(JNIEnv* env, jobject clazz, jlong interpHandle, jint index, jint msec, jfloatArray valueArray, jfloatArray blendArray)
{
- SkInterpolator* interp = reinterpret_cast<SkInterpolator*>(interpHandle);
+ SkiaInterpolator* interp = reinterpret_cast<SkiaInterpolator*>(interpHandle);
AutoJavaFloatArray autoValues(env, valueArray);
AutoJavaFloatArray autoBlend(env, blendArray, 4);
@@ -36,7 +36,7 @@ static void Interpolator_setKeyFrame(JNIEnv* env, jobject clazz, jlong interpHan
static void Interpolator_setRepeatMirror(JNIEnv* env, jobject clazz, jlong interpHandle, jfloat repeatCount, jboolean mirror)
{
- SkInterpolator* interp = reinterpret_cast<SkInterpolator*>(interpHandle);
+ SkiaInterpolator* interp = reinterpret_cast<SkiaInterpolator*>(interpHandle);
if (repeatCount > 32000)
repeatCount = 32000;
@@ -46,8 +46,8 @@ static void Interpolator_setRepeatMirror(JNIEnv* env, jobject clazz, jlong inter
static jint Interpolator_timeToValues(JNIEnv* env, jobject clazz, jlong interpHandle, jint msec, jfloatArray valueArray)
{
- SkInterpolator* interp = reinterpret_cast<SkInterpolator*>(interpHandle);
- SkInterpolatorBase::Result result;
+ SkiaInterpolator* interp = reinterpret_cast<SkiaInterpolator*>(interpHandle);
+ SkiaInterpolator::Result result;
float* values = valueArray ? env->GetFloatArrayElements(valueArray, NULL) : NULL;
result = interp->timeToValues(msec, (SkScalar*)values);
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index f24ba5c1c878..bd1da985a33e 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -34,14 +34,18 @@
#include <renderthread/RenderProxy.h>
#include <renderthread/RenderTask.h>
#include <renderthread/RenderThread.h>
+#include <thread/CommonPool.h>
#include <utils/Color.h>
#include <utils/RefBase.h>
#include <utils/StrongPointer.h>
#include <utils/Timers.h>
#include <utils/TraceUtils.h>
+#include <pthread.h>
+
#include <algorithm>
#include <atomic>
+#include <vector>
#include "android_graphics_HardwareRendererObserver.h"
@@ -53,6 +57,10 @@ using namespace android::uirenderer::renderthread;
struct {
jclass clazz;
jmethodID invokePictureCapturedCallback;
+ jmethodID createHintSession;
+ jmethodID updateTargetWorkDuration;
+ jmethodID reportActualWorkDuration;
+ jmethodID closeHintSession;
} gHardwareRenderer;
struct {
@@ -71,6 +79,14 @@ static JNIEnv* getenv(JavaVM* vm) {
return env;
}
+static bool hasExceptionAndClear(JNIEnv* env) {
+ if (GraphicsJNI::hasException(env)) {
+ env->ExceptionClear();
+ return true;
+ }
+ return false;
+}
+
typedef ANativeWindow* (*ANW_fromSurface)(JNIEnv* env, jobject surface);
ANW_fromSurface fromSurface;
@@ -120,6 +136,67 @@ private:
}
};
+class HintSessionWrapper : public LightRefBase<HintSessionWrapper> {
+public:
+ static sp<HintSessionWrapper> create(JNIEnv* env, RenderProxy* proxy) {
+ if (!Properties::useHintManager) return nullptr;
+
+ // Include UI thread (self), render thread, and thread pool.
+ std::vector<int> tids = CommonPool::getThreadIds();
+ tids.push_back(proxy->getRenderThreadTid());
+ tids.push_back(pthread_gettid_np(pthread_self()));
+
+ jintArray tidsArray = env->NewIntArray(tids.size());
+ if (hasExceptionAndClear(env)) return nullptr;
+ env->SetIntArrayRegion(tidsArray, 0, tids.size(), reinterpret_cast<jint*>(tids.data()));
+ if (hasExceptionAndClear(env)) return nullptr;
+ jobject session = env->CallStaticObjectMethod(
+ gHardwareRenderer.clazz, gHardwareRenderer.createHintSession, tidsArray);
+ if (hasExceptionAndClear(env) || !session) return nullptr;
+ return new HintSessionWrapper(env, session);
+ }
+
+ ~HintSessionWrapper() {
+ if (!mSession) return;
+ JNIEnv* env = getenv(mVm);
+ env->CallStaticVoidMethod(gHardwareRenderer.clazz, gHardwareRenderer.closeHintSession,
+ mSession);
+ hasExceptionAndClear(env);
+ env->DeleteGlobalRef(mSession);
+ mSession = nullptr;
+ }
+
+ void updateTargetWorkDuration(long targetDurationNanos) {
+ if (!mSession) return;
+ JNIEnv* env = getenv(mVm);
+ env->CallStaticVoidMethod(gHardwareRenderer.clazz,
+ gHardwareRenderer.updateTargetWorkDuration, mSession,
+ static_cast<jlong>(targetDurationNanos));
+ hasExceptionAndClear(env);
+ }
+
+ void reportActualWorkDuration(long actualDurationNanos) {
+ if (!mSession) return;
+ JNIEnv* env = getenv(mVm);
+ env->CallStaticVoidMethod(gHardwareRenderer.clazz,
+ gHardwareRenderer.reportActualWorkDuration, mSession,
+ static_cast<jlong>(actualDurationNanos));
+ hasExceptionAndClear(env);
+ }
+
+private:
+ HintSessionWrapper(JNIEnv* env, jobject jobject) {
+ env->GetJavaVM(&mVm);
+ if (jobject) {
+ mSession = env->NewGlobalRef(jobject);
+ LOG_ALWAYS_FATAL_IF(!mSession, "Failed to make global ref");
+ }
+ }
+
+ JavaVM* mVm = nullptr;
+ jobject mSession = nullptr;
+};
+
static void android_view_ThreadedRenderer_rotateProcessStatsBuffer(JNIEnv* env, jobject clazz) {
RenderProxy::rotateProcessStatsBuffer();
}
@@ -147,6 +224,12 @@ static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject claz
RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootRenderNodePtr);
ContextFactoryImpl factory(rootRenderNode);
RenderProxy* proxy = new RenderProxy(translucent, rootRenderNode, &factory);
+ sp<HintSessionWrapper> wrapper = HintSessionWrapper::create(env, proxy);
+ if (wrapper) {
+ proxy->setHintSessionCallbacks(
+ [wrapper](int64_t nanos) { wrapper->updateTargetWorkDuration(nanos); },
+ [wrapper](int64_t nanos) { wrapper->reportActualWorkDuration(nanos); });
+ }
return (jlong) proxy;
}
@@ -769,6 +852,18 @@ int register_android_view_ThreadedRenderer(JNIEnv* env) {
gHardwareRenderer.invokePictureCapturedCallback = GetStaticMethodIDOrDie(env, hardwareRenderer,
"invokePictureCapturedCallback",
"(JLandroid/graphics/HardwareRenderer$PictureCapturedCallback;)V");
+ gHardwareRenderer.createHintSession =
+ GetStaticMethodIDOrDie(env, hardwareRenderer, "createHintSession",
+ "([I)Landroid/os/PerformanceHintManager$Session;");
+ gHardwareRenderer.updateTargetWorkDuration =
+ GetStaticMethodIDOrDie(env, hardwareRenderer, "updateTargetWorkDuration",
+ "(Landroid/os/PerformanceHintManager$Session;J)V");
+ gHardwareRenderer.reportActualWorkDuration =
+ GetStaticMethodIDOrDie(env, hardwareRenderer, "reportActualWorkDuration",
+ "(Landroid/os/PerformanceHintManager$Session;J)V");
+ gHardwareRenderer.closeHintSession =
+ GetStaticMethodIDOrDie(env, hardwareRenderer, "closeHintSession",
+ "(Landroid/os/PerformanceHintManager$Session;)V");
jclass frameCallbackClass = FindClassOrDie(env,
"android/graphics/HardwareRenderer$FrameDrawingCallback");
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 3408ffda3f9d..7a38a3bc9c05 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -21,6 +21,7 @@
#include "../DeferredLayerUpdater.h"
#include "../DisplayList.h"
+#include "../Properties.h"
#include "../RenderNode.h"
#include "CanvasContext.h"
#include "RenderThread.h"
@@ -44,6 +45,12 @@ void DrawFrameTask::setContext(RenderThread* thread, CanvasContext* context,
mTargetNode = targetNode;
}
+void DrawFrameTask::setHintSessionCallbacks(std::function<void(int64_t)> updateTargetWorkDuration,
+ std::function<void(int64_t)> reportActualWorkDuration) {
+ mUpdateTargetWorkDuration = std::move(updateTargetWorkDuration);
+ mReportActualWorkDuration = std::move(reportActualWorkDuration);
+}
+
void DrawFrameTask::pushLayerUpdate(DeferredLayerUpdater* layer) {
LOG_ALWAYS_FATAL_IF(!mContext,
"Lifecycle violation, there's no context to pushLayerUpdate with!");
@@ -102,6 +109,9 @@ void DrawFrameTask::run() {
CanvasContext* context = mContext;
std::function<void(int64_t)> callback = std::move(mFrameCallback);
mFrameCallback = nullptr;
+ int64_t intendedVsync = mFrameInfo[static_cast<int>(FrameInfoIndex::IntendedVsync)];
+ int64_t frameDeadline = mFrameInfo[static_cast<int>(FrameInfoIndex::FrameDeadline)];
+ int64_t frameStartTime = mFrameInfo[static_cast<int>(FrameInfoIndex::FrameStartTime)];
// From this point on anything in "this" is *UNSAFE TO ACCESS*
if (canUnblockUiThread) {
@@ -124,6 +134,25 @@ void DrawFrameTask::run() {
if (!canUnblockUiThread) {
unblockUiThread();
}
+
+ // These member callbacks are effectively const as they are set once during init, so it's safe
+ // to use these directly instead of making local copies.
+ if (mUpdateTargetWorkDuration && mReportActualWorkDuration) {
+ constexpr int64_t kSanityCheckLowerBound = 100000; // 0.1ms
+ constexpr int64_t kSanityCheckUpperBound = 10000000000; // 10s
+ int64_t targetWorkDuration = frameDeadline - intendedVsync;
+ targetWorkDuration = targetWorkDuration * Properties::targetCpuTimePercentage / 100;
+ if (targetWorkDuration > kSanityCheckLowerBound &&
+ targetWorkDuration < kSanityCheckUpperBound &&
+ targetWorkDuration != mLastTargetWorkDuration) {
+ mLastTargetWorkDuration = targetWorkDuration;
+ mUpdateTargetWorkDuration(targetWorkDuration);
+ }
+ int64_t frameDuration = systemTime(SYSTEM_TIME_MONOTONIC) - frameStartTime;
+ if (frameDuration > kSanityCheckLowerBound && frameDuration < kSanityCheckUpperBound) {
+ mReportActualWorkDuration(frameDuration);
+ }
+ }
}
bool DrawFrameTask::syncFrameState(TreeInfo& info) {
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index 696cfaef3cd7..3bb574aff59b 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -61,6 +61,8 @@ public:
virtual ~DrawFrameTask();
void setContext(RenderThread* thread, CanvasContext* context, RenderNode* targetNode);
+ void setHintSessionCallbacks(std::function<void(int64_t)> updateTargetWorkDuration,
+ std::function<void(int64_t)> reportActualWorkDuration);
void setContentDrawBounds(int left, int top, int right, int bottom) {
mContentDrawBounds.set(left, top, right, bottom);
}
@@ -107,6 +109,10 @@ private:
std::function<void(int64_t)> mFrameCallback;
std::function<void(int64_t)> mFrameCompleteCallback;
+
+ nsecs_t mLastTargetWorkDuration = 0;
+ std::function<void(int64_t)> mUpdateTargetWorkDuration;
+ std::function<void(int64_t)> mReportActualWorkDuration;
};
} /* namespace renderthread */
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 423cc08189ca..9361abd20852 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -76,6 +76,12 @@ void RenderProxy::setName(const char* name) {
mRenderThread.queue().runSync([this, name]() { mContext->setName(std::string(name)); });
}
+void RenderProxy::setHintSessionCallbacks(std::function<void(int64_t)> updateTargetWorkDuration,
+ std::function<void(int64_t)> reportActualWorkDuration) {
+ mDrawFrameTask.setHintSessionCallbacks(std::move(updateTargetWorkDuration),
+ std::move(reportActualWorkDuration));
+}
+
void RenderProxy::setSurface(ANativeWindow* window, bool enableTimeout) {
if (window) { ANativeWindow_acquire(window); }
mRenderThread.queue().post([this, win = window, enableTimeout]() mutable {
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 366d6b5a172c..8d55d3c55570 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -71,6 +71,8 @@ public:
void setSwapBehavior(SwapBehavior swapBehavior);
bool loadSystemProperties();
void setName(const char* name);
+ void setHintSessionCallbacks(std::function<void(int64_t)> updateTargetWorkDuration,
+ std::function<void(int64_t)> reportActualWorkDuration);
void setSurface(ANativeWindow* window, bool enableTimeout = true);
void setSurfaceControl(ASurfaceControl* surfaceControl);
diff --git a/libs/hwui/thread/CommonPool.cpp b/libs/hwui/thread/CommonPool.cpp
index d011bdfe945e..dc92f9f0d39a 100644
--- a/libs/hwui/thread/CommonPool.cpp
+++ b/libs/hwui/thread/CommonPool.cpp
@@ -29,14 +29,23 @@ CommonPool::CommonPool() {
ATRACE_CALL();
CommonPool* pool = this;
+ std::mutex mLock;
+ std::vector<int> tids(THREAD_COUNT);
+ std::vector<std::condition_variable> tidConditionVars(THREAD_COUNT);
+
// Create 2 workers
for (int i = 0; i < THREAD_COUNT; i++) {
- std::thread worker([pool, i] {
+ std::thread worker([pool, i, &mLock, &tids, &tidConditionVars] {
{
std::array<char, 20> name{"hwuiTask"};
snprintf(name.data(), name.size(), "hwuiTask%d", i);
auto self = pthread_self();
pthread_setname_np(self, name.data());
+ {
+ std::unique_lock lock(mLock);
+ tids[i] = pthread_gettid_np(self);
+ tidConditionVars[i].notify_one();
+ }
setpriority(PRIO_PROCESS, 0, PRIORITY_FOREGROUND);
auto startHook = renderthread::RenderThread::getOnStartHook();
if (startHook) {
@@ -47,6 +56,15 @@ CommonPool::CommonPool() {
});
worker.detach();
}
+ {
+ std::unique_lock lock(mLock);
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ while (!tids[i]) {
+ tidConditionVars[i].wait(lock);
+ }
+ }
+ }
+ mWorkerThreadIds = std::move(tids);
}
CommonPool& CommonPool::instance() {
@@ -58,6 +76,10 @@ void CommonPool::post(Task&& task) {
instance().enqueue(std::move(task));
}
+std::vector<int> CommonPool::getThreadIds() {
+ return instance().mWorkerThreadIds;
+}
+
void CommonPool::enqueue(Task&& task) {
std::unique_lock lock(mLock);
while (!mWorkQueue.hasSpace()) {
@@ -104,4 +126,4 @@ void CommonPool::doWaitForIdle() {
}
} // namespace uirenderer
-} // namespace android \ No newline at end of file
+} // namespace android
diff --git a/libs/hwui/thread/CommonPool.h b/libs/hwui/thread/CommonPool.h
index 7603eeef4692..74f852bd1413 100644
--- a/libs/hwui/thread/CommonPool.h
+++ b/libs/hwui/thread/CommonPool.h
@@ -25,6 +25,7 @@
#include <functional>
#include <future>
#include <mutex>
+#include <vector>
namespace android {
namespace uirenderer {
@@ -97,6 +98,8 @@ public:
return task.get_future().get();
};
+ static std::vector<int> getThreadIds();
+
// For testing purposes only, blocks until all worker threads are parked.
static void waitForIdle();
@@ -111,6 +114,8 @@ private:
void workerLoop();
+ std::vector<int> mWorkerThreadIds;
+
std::mutex mLock;
std::condition_variable mCondition;
int mWaitingThreads = 0;
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index 9300f13e03cb..09b382ee46d0 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -20,6 +20,7 @@ import android.Manifest;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
+import android.annotation.TestApi;
import android.util.SparseIntArray;
import java.lang.annotation.Retention;
@@ -172,6 +173,11 @@ public final class AudioDeviceInfo {
@RequiresPermission(Manifest.permission.CAPTURE_AUDIO_OUTPUT)
public static final int TYPE_ECHO_REFERENCE = 28;
+ /**
+ * A device type describing the Enhanced Audio Return Channel of an HDMI connection.
+ */
+ public static final int TYPE_HDMI_EARC = 29;
+
/** @hide */
@IntDef(flag = false, prefix = "TYPE", value = {
TYPE_BUILTIN_EARPIECE,
@@ -188,6 +194,7 @@ public final class AudioDeviceInfo {
TYPE_TELEPHONY,
TYPE_LINE_ANALOG,
TYPE_HDMI_ARC,
+ TYPE_HDMI_EARC,
TYPE_LINE_DIGITAL,
TYPE_FM,
TYPE_AUX_LINE,
@@ -197,6 +204,8 @@ public final class AudioDeviceInfo {
TYPE_BUILTIN_MIC,
TYPE_FM_TUNER,
TYPE_TV_TUNER,
+ TYPE_BUILTIN_SPEAKER_SAFE,
+ TYPE_REMOTE_SUBMIX,
TYPE_BLE_HEADSET,
TYPE_BLE_SPEAKER,
TYPE_ECHO_REFERENCE}
@@ -222,7 +231,10 @@ public final class AudioDeviceInfo {
TYPE_LINE_DIGITAL,
TYPE_IP,
TYPE_BUS,
+ TYPE_REMOTE_SUBMIX,
TYPE_BLE_HEADSET,
+ TYPE_HDMI_ARC,
+ TYPE_HDMI_EARC,
TYPE_ECHO_REFERENCE}
)
@Retention(RetentionPolicy.SOURCE)
@@ -244,12 +256,14 @@ public final class AudioDeviceInfo {
TYPE_TELEPHONY,
TYPE_LINE_ANALOG,
TYPE_HDMI_ARC,
+ TYPE_HDMI_EARC,
TYPE_LINE_DIGITAL,
TYPE_FM,
TYPE_AUX_LINE,
TYPE_IP,
TYPE_BUS,
TYPE_HEARING_AID,
+ TYPE_BUILTIN_SPEAKER_SAFE,
TYPE_BLE_HEADSET,
TYPE_BLE_SPEAKER}
)
@@ -273,6 +287,7 @@ public final class AudioDeviceInfo {
case TYPE_TELEPHONY:
case TYPE_LINE_ANALOG:
case TYPE_HDMI_ARC:
+ case TYPE_HDMI_EARC:
case TYPE_LINE_DIGITAL:
case TYPE_FM:
case TYPE_AUX_LINE:
@@ -309,6 +324,8 @@ public final class AudioDeviceInfo {
case TYPE_BUS:
case TYPE_REMOTE_SUBMIX:
case TYPE_BLE_HEADSET:
+ case TYPE_HDMI_ARC:
+ case TYPE_HDMI_EARC:
case TYPE_ECHO_REFERENCE:
return true;
default:
@@ -318,9 +335,15 @@ public final class AudioDeviceInfo {
/**
* @hide
- * Throws IAE on an invalid output device type
+ * Enforces whether the audio device type is acceptable for output.
+ *
+ * A vendor implemented output type should modify isValidAudioDeviceTypeOut()
+ * appropriately to accept the new type. Do not remove already acceptable types.
+ *
+ * @throws IllegalArgumentException on an invalid output device type.
* @param type
*/
+ @TestApi
public static void enforceValidAudioDeviceTypeOut(int type) {
if (!isValidAudioDeviceTypeOut(type)) {
throw new IllegalArgumentException("Illegal output device type " + type);
@@ -329,9 +352,15 @@ public final class AudioDeviceInfo {
/**
* @hide
- * Throws IAE on an invalid input device type
+ * Enforces whether the audio device type is acceptable for input.
+ *
+ * A vendor implemented input type should modify isValidAudioDeviceTypeIn()
+ * appropriately to accept the new type. Do not remove already acceptable types.
+ *
+ * @throws IllegalArgumentException on an invalid input device type.
* @param type
*/
+ @TestApi
public static void enforceValidAudioDeviceTypeIn(int type) {
if (!isValidAudioDeviceTypeIn(type)) {
throw new IllegalArgumentException("Illegal input device type " + type);
@@ -609,6 +638,7 @@ public final class AudioDeviceInfo {
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_TELEPHONY_TX, TYPE_TELEPHONY);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_LINE, TYPE_LINE_ANALOG);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HDMI_ARC, TYPE_HDMI_ARC);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HDMI_EARC, TYPE_HDMI_EARC);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_SPDIF, TYPE_LINE_DIGITAL);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_FM, TYPE_FM);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_AUX_LINE, TYPE_AUX_LINE);
@@ -641,6 +671,8 @@ public final class AudioDeviceInfo {
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BUS, TYPE_BUS);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_REMOTE_SUBMIX, TYPE_REMOTE_SUBMIX);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLE_HEADSET, TYPE_BLE_HEADSET);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_HDMI_ARC, TYPE_HDMI_ARC);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_HDMI_EARC, TYPE_HDMI_EARC);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_ECHO_REFERENCE, TYPE_ECHO_REFERENCE);
@@ -656,6 +688,7 @@ public final class AudioDeviceInfo {
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLUETOOTH_A2DP, AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_HDMI, AudioSystem.DEVICE_OUT_HDMI);
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_HDMI_ARC, AudioSystem.DEVICE_OUT_HDMI_ARC);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_HDMI_EARC, AudioSystem.DEVICE_OUT_HDMI_EARC);
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_DEVICE, AudioSystem.DEVICE_OUT_USB_DEVICE);
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_HEADSET, AudioSystem.DEVICE_OUT_USB_HEADSET);
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_ACCESSORY, AudioSystem.DEVICE_OUT_USB_ACCESSORY);
@@ -700,6 +733,8 @@ public final class AudioDeviceInfo {
EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
TYPE_REMOTE_SUBMIX, AudioSystem.DEVICE_IN_REMOTE_SUBMIX);
EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_BLE_HEADSET, AudioSystem.DEVICE_IN_BLE_HEADSET);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_HDMI_ARC, AudioSystem.DEVICE_IN_HDMI_ARC);
+ EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_HDMI_EARC, AudioSystem.DEVICE_IN_HDMI_EARC);
EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
TYPE_ECHO_REFERENCE, AudioSystem.DEVICE_IN_ECHO_REFERENCE);
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 5332d751b265..85d1bc533401 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -5189,6 +5189,10 @@ public class AudioManager {
*/
public static final int DEVICE_OUT_HDMI_ARC = AudioSystem.DEVICE_OUT_HDMI_ARC;
/** @hide
+ * The audio output device code for HDMI enhanced Audio Return Channel.
+ */
+ public static final int DEVICE_OUT_HDMI_EARC = AudioSystem.DEVICE_OUT_HDMI_EARC;
+ /** @hide
* The audio output device code for S/PDIF digital connection.
*/
public static final int DEVICE_OUT_SPDIF = AudioSystem.DEVICE_OUT_SPDIF;
@@ -5241,6 +5245,12 @@ public class AudioManager {
AudioSystem.DEVICE_IN_HDMI_ARC;
/** @hide
+ * The audio input device code for HDMI EARC
+ */
+ public static final int DEVICE_IN_HDMI_EARC =
+ AudioSystem.DEVICE_IN_HDMI_EARC;
+
+ /** @hide
* The audio input device code for telephony voice RX path
*/
public static final int DEVICE_IN_TELEPHONY_RX =
@@ -5354,6 +5364,7 @@ public class AudioManager {
* {@link #DEVICE_OUT_TELEPHONY_TX}.
* {@link #DEVICE_OUT_LINE}.
* {@link #DEVICE_OUT_HDMI_ARC}.
+ * {@link #DEVICE_OUT_HDMI_EARC}.
* {@link #DEVICE_OUT_SPDIF}.
* {@link #DEVICE_OUT_FM}.
* {@link #DEVICE_OUT_DEFAULT} is not used here.
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 5f60fb63a334..363da248eb96 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -890,6 +890,8 @@ public class AudioSystem
/** @hide */
public static final int DEVICE_OUT_HDMI_ARC = 0x40000;
/** @hide */
+ public static final int DEVICE_OUT_HDMI_EARC = 0x40001;
+ /** @hide */
public static final int DEVICE_OUT_SPDIF = 0x80000;
/** @hide */
@UnsupportedAppUsage
@@ -961,6 +963,7 @@ public class AudioSystem
DEVICE_OUT_ALL_SET.add(DEVICE_OUT_TELEPHONY_TX);
DEVICE_OUT_ALL_SET.add(DEVICE_OUT_LINE);
DEVICE_OUT_ALL_SET.add(DEVICE_OUT_HDMI_ARC);
+ DEVICE_OUT_ALL_SET.add(DEVICE_OUT_HDMI_EARC);
DEVICE_OUT_ALL_SET.add(DEVICE_OUT_SPDIF);
DEVICE_OUT_ALL_SET.add(DEVICE_OUT_FM);
DEVICE_OUT_ALL_SET.add(DEVICE_OUT_AUX_LINE);
@@ -993,6 +996,7 @@ public class AudioSystem
DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET = new HashSet<>();
DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET.add(DEVICE_OUT_AUX_LINE);
DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET.add(DEVICE_OUT_HDMI_ARC);
+ DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET.add(DEVICE_OUT_HDMI_EARC);
DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET.add(DEVICE_OUT_SPDIF);
DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET = new HashSet<>();
@@ -1074,6 +1078,8 @@ public class AudioSystem
/** @hide */
public static final int DEVICE_IN_HDMI_ARC = DEVICE_BIT_IN | 0x8000000;
/** @hide */
+ public static final int DEVICE_IN_HDMI_EARC = DEVICE_BIT_IN | 0x8000001;
+ /** @hide */
public static final int DEVICE_IN_ECHO_REFERENCE = DEVICE_BIT_IN | 0x10000000;
/** @hide */
public static final int DEVICE_IN_BLE_HEADSET = DEVICE_BIT_IN | 0x20000000;
@@ -1114,6 +1120,7 @@ public class AudioSystem
DEVICE_IN_ALL_SET.add(DEVICE_IN_USB_HEADSET);
DEVICE_IN_ALL_SET.add(DEVICE_IN_BLUETOOTH_BLE);
DEVICE_IN_ALL_SET.add(DEVICE_IN_HDMI_ARC);
+ DEVICE_IN_ALL_SET.add(DEVICE_IN_HDMI_EARC);
DEVICE_IN_ALL_SET.add(DEVICE_IN_ECHO_REFERENCE);
DEVICE_IN_ALL_SET.add(DEVICE_IN_BLE_HEADSET);
DEVICE_IN_ALL_SET.add(DEVICE_IN_DEFAULT);
@@ -1169,6 +1176,7 @@ public class AudioSystem
/** @hide */ public static final String DEVICE_OUT_TELEPHONY_TX_NAME = "telephony_tx";
/** @hide */ public static final String DEVICE_OUT_LINE_NAME = "line";
/** @hide */ public static final String DEVICE_OUT_HDMI_ARC_NAME = "hmdi_arc";
+ /** @hide */ public static final String DEVICE_OUT_HDMI_EARC_NAME = "hmdi_earc";
/** @hide */ public static final String DEVICE_OUT_SPDIF_NAME = "spdif";
/** @hide */ public static final String DEVICE_OUT_FM_NAME = "fm_transmitter";
/** @hide */ public static final String DEVICE_OUT_AUX_LINE_NAME = "aux_line";
@@ -1208,6 +1216,7 @@ public class AudioSystem
/** @hide */ public static final String DEVICE_IN_BLUETOOTH_BLE_NAME = "bt_ble";
/** @hide */ public static final String DEVICE_IN_ECHO_REFERENCE_NAME = "echo_reference";
/** @hide */ public static final String DEVICE_IN_HDMI_ARC_NAME = "hdmi_arc";
+ /** @hide */ public static final String DEVICE_IN_HDMI_EARC_NAME = "hdmi_earc";
/** @hide */ public static final String DEVICE_IN_BLE_HEADSET_NAME = "ble_headset";
/** @hide */
@@ -1253,6 +1262,8 @@ public class AudioSystem
return DEVICE_OUT_LINE_NAME;
case DEVICE_OUT_HDMI_ARC:
return DEVICE_OUT_HDMI_ARC_NAME;
+ case DEVICE_OUT_HDMI_EARC:
+ return DEVICE_OUT_HDMI_EARC_NAME;
case DEVICE_OUT_SPDIF:
return DEVICE_OUT_SPDIF_NAME;
case DEVICE_OUT_FM:
@@ -1339,6 +1350,8 @@ public class AudioSystem
return DEVICE_IN_ECHO_REFERENCE_NAME;
case DEVICE_IN_HDMI_ARC:
return DEVICE_IN_HDMI_ARC_NAME;
+ case DEVICE_IN_HDMI_EARC:
+ return DEVICE_IN_HDMI_EARC_NAME;
case DEVICE_IN_BLE_HEADSET:
return DEVICE_IN_BLE_HEADSET_NAME;
case DEVICE_IN_DEFAULT:
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 4968bd1e0ce7..cc05ecd3f18e 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -4742,6 +4742,25 @@ final public class MediaCodec {
return mType;
}
+ @Override
+ public boolean equals(Object o) {
+ if (o == null) {
+ return false;
+ }
+ if (!(o instanceof ParameterDescriptor)) {
+ return false;
+ }
+ ParameterDescriptor other = (ParameterDescriptor) o;
+ return this.mName.equals(other.mName) && this.mType == other.mType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.asList(
+ (Object) mName,
+ (Object) Integer.valueOf(mType)).hashCode();
+ }
+
private String mName;
private @MediaFormat.Type int mType;
}
@@ -4766,7 +4785,8 @@ final public class MediaCodec {
private native ParameterDescriptor native_getParameterDescriptor(@NonNull String name);
/**
- * Subscribe to vendor parameters, so that changes to these parameters generate
+ * Subscribe to vendor parameters, so that these parameters will be present in
+ * {@link #getOutputFormat} and changes to these parameters generate
* output format change event.
* <p>
* Unrecognized parameter names or standard (non-vendor) parameter names will be ignored.
@@ -4795,8 +4815,9 @@ final public class MediaCodec {
private native void native_subscribeToVendorParameters(@NonNull List<String> names);
/**
- * Unsubscribe from vendor parameters, so that changes to these parameters
- * no longer generate output format change event.
+ * Unsubscribe from vendor parameters, so that these parameters will not be present in
+ * {@link #getOutputFormat} and changes to these parameters no longer generate
+ * output format change event.
* <p>
* Unrecognized parameter names, standard (non-vendor) parameter names will be ignored.
* {@link #reset} also resets the list of subscribed parameters.
@@ -4804,7 +4825,8 @@ final public class MediaCodec {
* <p>
* This method can be called in any codec state except for released state. When called in
* running state with newly unsubscribed parameters, it takes effect no later than the
- * processing of the subsequently queued buffer.
+ * processing of the subsequently queued buffer. For the removed parameters, the codec will
+ * generate output format change event.
* <p>
* Note that any vendor parameters set in a {@link #configure} or
* {@link #setParameters} call are automatically subscribed, and with this method
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index e0f637959cfb..7433cf970566 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -432,14 +432,27 @@ void ASurfaceTransaction_setGeometry(ASurfaceTransaction* aSurfaceTransaction,
const ARect& destination, int32_t transform) {
CHECK_NOT_NULL(aSurfaceTransaction);
CHECK_NOT_NULL(aSurfaceControl);
- CHECK_VALID_RECT(source);
CHECK_VALID_RECT(destination);
+ Rect sourceRect = static_cast<const Rect&>(source);
+ // Adjust the source so its top and left are not negative
+ sourceRect.left = std::max(sourceRect.left, 0);
+ sourceRect.top = std::max(sourceRect.top, 0);
+ LOG_ALWAYS_FATAL_IF(sourceRect.isEmpty(), "invalid arg passed as source argument");
+
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
- transaction->setCrop(surfaceControl, static_cast<const Rect&>(source));
- transaction->setFrame(surfaceControl, static_cast<const Rect&>(destination));
+ transaction->setCrop(surfaceControl, sourceRect);
+
+ float dsdx = (destination.right - destination.left) /
+ static_cast<float>(sourceRect.right - sourceRect.left);
+ float dsdy = (destination.bottom - destination.top) /
+ static_cast<float>(sourceRect.bottom - sourceRect.top);
+
+ transaction->setPosition(surfaceControl, destination.left - (sourceRect.left * dsdx),
+ destination.top - (sourceRect.top * dsdy));
+ transaction->setMatrix(surfaceControl, dsdx, 0, 0, dsdy);
transaction->setTransform(surfaceControl, transform);
bool transformToInverseDisplay = (NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY & transform) ==
NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
@@ -458,16 +471,18 @@ void ASurfaceTransaction_setSourceRect(ASurfaceTransaction* aSurfaceTransaction,
transaction->setCrop(surfaceControl, static_cast<const Rect&>(source));
}
-void ASurfaceTransaction_setPosition(ASurfaceTransaction* aSurfaceTransaction,
- ASurfaceControl* aSurfaceControl, const ARect& destination) {
- CHECK_NOT_NULL(aSurfaceTransaction);
+void ASurfaceTransaction_setPosition(ASurfaceTransaction* /* aSurfaceTransaction */,
+ ASurfaceControl* /* aSurfaceControl */,
+ const ARect& /* destination */) {
+ // TODO: Fix this function
+ /* CHECK_NOT_NULL(aSurfaceTransaction);
CHECK_NOT_NULL(aSurfaceControl);
CHECK_VALID_RECT(destination);
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
- transaction->setFrame(surfaceControl, static_cast<const Rect&>(destination));
+ transaction->setFrame(surfaceControl, static_cast<const Rect&>(destination));*/
}
void ASurfaceTransaction_setTransform(ASurfaceTransaction* aSurfaceTransaction,
diff --git a/packages/Android.bp b/packages/Android.bp
new file mode 100644
index 000000000000..8b0698bc4339
--- /dev/null
+++ b/packages/Android.bp
@@ -0,0 +1,28 @@
+// 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.
+
+// Defaults for platform apps
+java_defaults {
+ name: "platform_app_defaults",
+ plugins: ["error_prone_android_framework"],
+ errorprone: {
+ javacflags: [
+ // We're less worried about performance in app code
+ "-Xep:AndroidFrameworkEfficientCollections:OFF",
+ "-Xep:AndroidFrameworkEfficientParcelable:OFF",
+ "-Xep:AndroidFrameworkEfficientStrings:OFF",
+ "-Xep:AndroidFrameworkEfficientXml:OFF",
+ ],
+ },
+}
diff --git a/packages/Connectivity/framework/Android.bp b/packages/Connectivity/framework/Android.bp
index 5f5ebf410f21..c62402d7d4c9 100644
--- a/packages/Connectivity/framework/Android.bp
+++ b/packages/Connectivity/framework/Android.bp
@@ -105,6 +105,7 @@ java_sdk_library {
"//frameworks/libs/net/common/testutils",
"//frameworks/libs/net/common/tests:__subpackages__",
"//frameworks/opt/telephony/tests/telephonytests",
+ "//packages/modules/CaptivePortalLogin/tests",
"//packages/modules/Connectivity/Tethering/tests:__subpackages__",
"//packages/modules/Connectivity/tests:__subpackages__",
"//packages/modules/NetworkStack/tests:__subpackages__",
diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt
index caf7f49efcd8..4719772075ce 100644
--- a/packages/Connectivity/framework/api/module-lib-current.txt
+++ b/packages/Connectivity/framework/api/module-lib-current.txt
@@ -133,16 +133,6 @@ package android.net {
method @NonNull public android.net.NetworkRequest.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>);
}
- public final class TcpRepairWindow {
- ctor public TcpRepairWindow(int, int, int, int, int, int);
- field public final int maxWindow;
- field public final int rcvWnd;
- field public final int rcvWndScale;
- field public final int rcvWup;
- field public final int sndWl1;
- field public final int sndWnd;
- }
-
public final class TestNetworkInterface implements android.os.Parcelable {
ctor public TestNetworkInterface(@NonNull android.os.ParcelFileDescriptor, @NonNull String);
method public int describeContents();
diff --git a/packages/Connectivity/framework/api/system-current.txt b/packages/Connectivity/framework/api/system-current.txt
index 2ac019d7b8ec..63e0fe945abb 100644
--- a/packages/Connectivity/framework/api/system-current.txt
+++ b/packages/Connectivity/framework/api/system-current.txt
@@ -260,15 +260,15 @@ package android.net {
public static final class NetworkAgentConfig.Builder {
ctor public NetworkAgentConfig.Builder();
method @NonNull public android.net.NetworkAgentConfig build();
- method @NonNull public android.net.NetworkAgentConfig.Builder disableNat64Detection();
- method @NonNull public android.net.NetworkAgentConfig.Builder disableProvisioningNotification();
method @NonNull public android.net.NetworkAgentConfig.Builder setExplicitlySelected(boolean);
method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyExtraInfo(@NonNull String);
method @NonNull public android.net.NetworkAgentConfig.Builder setLegacySubType(int);
method @NonNull public android.net.NetworkAgentConfig.Builder setLegacySubTypeName(@NonNull String);
method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyType(int);
method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyTypeName(@NonNull String);
+ method @NonNull public android.net.NetworkAgentConfig.Builder setNat64DetectionEnabled(boolean);
method @NonNull public android.net.NetworkAgentConfig.Builder setPartialConnectivityAcceptable(boolean);
+ method @NonNull public android.net.NetworkAgentConfig.Builder setProvisioningNotificationEnabled(boolean);
method @NonNull public android.net.NetworkAgentConfig.Builder setUnvalidatedConnectivityAcceptable(boolean);
}
diff --git a/packages/Connectivity/framework/lint-baseline.xml b/packages/Connectivity/framework/lint-baseline.xml
new file mode 100644
index 000000000000..df37ae851438
--- /dev/null
+++ b/packages/Connectivity/framework/lint-baseline.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `new android.net.ParseException`"
+ errorLine1=" ParseException pe = new ParseException(e.reason, e.getCause());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/Connectivity/framework/src/android/net/DnsResolver.java"
+ line="301"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 30): `android.telephony.TelephonyCallback`"
+ errorLine1=" protected class ActiveDataSubscriptionIdListener extends TelephonyCallback"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java"
+ line="96"
+ column="62"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 30): `android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener`"
+ errorLine1=" implements TelephonyCallback.ActiveDataSubscriptionIdListener {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java"
+ line="97"
+ column="24"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.TelephonyManager#registerTelephonyCallback`"
+ errorLine1=" ctx.getSystemService(TelephonyManager.class).registerTelephonyCallback("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java"
+ line="126"
+ column="54"/>
+ </issue>
+
+</issues>
diff --git a/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java b/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java
index 3f058d8cbf12..ad8396b06ddf 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java
@@ -311,26 +311,28 @@ public final class NetworkAgentConfig implements Parcelable {
}
/**
- * Disables active detection of NAT64 (e.g., via RFC 7050 DNS lookups). Used to save power
- * and reduce idle traffic on networks that are known to be IPv6-only without a NAT64.
+ * Enables or disables active detection of NAT64 (e.g., via RFC 7050 DNS lookups). Used to
+ * save power and reduce idle traffic on networks that are known to be IPv6-only without a
+ * NAT64. By default, NAT64 detection is enabled.
*
* @return this builder, to facilitate chaining.
*/
@NonNull
- public Builder disableNat64Detection() {
- mConfig.skip464xlat = true;
+ public Builder setNat64DetectionEnabled(boolean enabled) {
+ mConfig.skip464xlat = !enabled;
return this;
}
/**
- * Disables the "Sign in to network" notification. Used if the network transport will
- * perform its own carrier-specific provisioning procedure.
+ * Enables or disables the "Sign in to network" notification. Used if the network transport
+ * will perform its own carrier-specific provisioning procedure. By default, the
+ * notification is enabled.
*
* @return this builder, to facilitate chaining.
*/
@NonNull
- public Builder disableProvisioningNotification() {
- mConfig.provisioningNotificationDisabled = true;
+ public Builder setProvisioningNotificationEnabled(boolean enabled) {
+ mConfig.provisioningNotificationDisabled = !enabled;
return this;
}
diff --git a/packages/Connectivity/framework/src/android/net/TcpRepairWindow.java b/packages/Connectivity/framework/src/android/net/TcpRepairWindow.java
index f062fa9034ea..86034f0a76ed 100644
--- a/packages/Connectivity/framework/src/android/net/TcpRepairWindow.java
+++ b/packages/Connectivity/framework/src/android/net/TcpRepairWindow.java
@@ -16,15 +16,12 @@
package android.net;
-import android.annotation.SystemApi;
-
/**
* Corresponds to C's {@code struct tcp_repair_window} from
* include/uapi/linux/tcp.h
*
* @hide
*/
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public final class TcpRepairWindow {
public final int sndWl1;
public final int sndWnd;
diff --git a/packages/Connectivity/framework/src/android/net/UidRange.java b/packages/Connectivity/framework/src/android/net/UidRange.java
index bc67c745c98f..bd332928f463 100644
--- a/packages/Connectivity/framework/src/android/net/UidRange.java
+++ b/packages/Connectivity/framework/src/android/net/UidRange.java
@@ -46,8 +46,8 @@ public final class UidRange implements Parcelable {
/** Creates a UidRange for the specified user. */
public static UidRange createForUser(UserHandle user) {
final UserHandle nextUser = UserHandle.of(user.getIdentifier() + 1);
- final int start = UserHandle.getUid(user, 0 /* appId */);
- final int end = UserHandle.getUid(nextUser, 0) - 1;
+ final int start = user.getUid(0 /* appId */);
+ final int end = nextUser.getUid(0 /* appId */) - 1;
return new UidRange(start, end);
}
diff --git a/packages/Connectivity/service/lint-baseline.xml b/packages/Connectivity/service/lint-baseline.xml
new file mode 100644
index 000000000000..35ea2d378e93
--- /dev/null
+++ b/packages/Connectivity/service/lint-baseline.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.TelephonyManager#isDataCapable`"
+ errorLine1=" if (tm.isDataCapable()) {"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/services/core/java/com/android/server/ConnectivityService.java"
+ line="781"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.content.Context#sendStickyBroadcast`"
+ errorLine1=" mUserAllContext.sendStickyBroadcast(intent, options);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/services/core/java/com/android/server/ConnectivityService.java"
+ line="2633"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.content.pm.PackageManager#getTargetSdkVersion`"
+ errorLine1=" final int callingVersion = pm.getTargetSdkVersion(callingPackageName);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/services/core/java/com/android/server/ConnectivityService.java"
+ line="5784"
+ column="43"/>
+ </issue>
+
+</issues>
diff --git a/packages/SettingsLib/ActionBarShadow/lint-baseline.xml b/packages/SettingsLib/ActionBarShadow/lint-baseline.xml
new file mode 100644
index 000000000000..4d5de5f46894
--- /dev/null
+++ b/packages/SettingsLib/ActionBarShadow/lint-baseline.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.view.View#setOnScrollChangeListener`"
+ errorLine1=" mScrollView.setOnScrollChangeListener(mScrollChangeWatcher);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/ActionBarShadow/src/com/android/settingslib/widget/ActionBarShadowController.java"
+ line="81"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.view.View#setOnScrollChangeListener`"
+ errorLine1=" mScrollView.setOnScrollChangeListener(null);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/ActionBarShadow/src/com/android/settingslib/widget/ActionBarShadowController.java"
+ line="88"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 23 (current min is 21): `android.view.View.OnScrollChangeListener`"
+ errorLine1=" final class ScrollChangeWatcher implements View.OnScrollChangeListener {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/ActionBarShadow/src/com/android/settingslib/widget/ActionBarShadowController.java"
+ line="95"
+ column="48"/>
+ </issue>
+
+</issues>
diff --git a/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml b/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml
new file mode 100644
index 000000000000..a19f7afbb5f8
--- /dev/null
+++ b/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="`android:Widget.DeviceDefault.Button.Borderless.Colored` requires API level 28 (current min is 21)"
+ errorLine1=" &lt;style name=&quot;SettingsActionButton&quot; parent=&quot;android:Widget.DeviceDefault.Button.Borderless.Colored&quot;>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml"
+ line="19"
+ column="40"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="`android:drawableTint` requires API level 23 (current min is 21)"
+ errorLine1=" &lt;item name=&quot;android:drawableTint&quot;>@*android:color/btn_colored_borderless_text_material&lt;/item>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml"
+ line="21"
+ column="15"/>
+ </issue>
+
+</issues>
diff --git a/packages/SettingsLib/AdaptiveIcon/lint-baseline.xml b/packages/SettingsLib/AdaptiveIcon/lint-baseline.xml
new file mode 100644
index 000000000000..7f1651721d84
--- /dev/null
+++ b/packages/SettingsLib/AdaptiveIcon/lint-baseline.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.content.res.Resources#getColor`"
+ errorLine1=" .getColor(colorRes, null /* theme */);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java"
+ line="78"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.content.Context#getColor`"
+ errorLine1=" setBackgroundColor(context.getColor(R.color.homepage_generic_icon_background));"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java"
+ line="90"
+ column="36"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 23 (current min is 21): `android.graphics.drawable.DrawableWrapper`"
+ errorLine1="public class AdaptiveOutlineDrawable extends DrawableWrapper {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java"
+ line="43"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `new android.graphics.drawable.DrawableWrapper`"
+ errorLine1=" super(new AdaptiveIconShapeDrawable(resources));"
+ errorLine2=" ~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java"
+ line="65"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `new android.graphics.drawable.DrawableWrapper`"
+ errorLine1=" super(new AdaptiveIconShapeDrawable(resources));"
+ errorLine2=" ~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java"
+ line="72"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.graphics.drawable.DrawableWrapper#getDrawable`"
+ errorLine1=" getDrawable().setTint(Color.WHITE);"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java"
+ line="80"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.content.res.Resources#getColor`"
+ errorLine1=" return resources.getColor(resId, /* theme */ null);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java"
+ line="105"
+ column="26"/>
+ </issue>
+
+</issues>
diff --git a/packages/SettingsLib/BannerMessagePreference/lint-baseline.xml b/packages/SettingsLib/BannerMessagePreference/lint-baseline.xml
new file mode 100644
index 000000000000..ba02a1fae9e0
--- /dev/null
+++ b/packages/SettingsLib/BannerMessagePreference/lint-baseline.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="`@android:style/Widget.DeviceDefault.Button.Borderless.Colored` requires API level 28 (current min is 21)"
+ errorLine1=" style=&quot;@android:style/Widget.DeviceDefault.Button.Borderless.Colored&quot;/>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/BannerMessagePreference/res/layout/banner_message.xml"
+ line="65"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="`@android:style/Widget.DeviceDefault.Button.Borderless.Colored` requires API level 28 (current min is 21)"
+ errorLine1=" style=&quot;@android:style/Widget.DeviceDefault.Button.Borderless.Colored&quot;/>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/BannerMessagePreference/res/layout/banner_message.xml"
+ line="71"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="`?android:attr/colorError` requires API level 26 (current min is 21)"
+ errorLine1=" android:fillColor=&quot;?android:attr/colorError&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/BannerMessagePreference/res/drawable/ic_warning.xml"
+ line="24"
+ column="9"/>
+ </issue>
+
+</issues>
diff --git a/packages/SettingsLib/BarChartPreference/lint-baseline.xml b/packages/SettingsLib/BarChartPreference/lint-baseline.xml
new file mode 100644
index 000000000000..f1043bb62fe1
--- /dev/null
+++ b/packages/SettingsLib/BarChartPreference/lint-baseline.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="`@android:style/Widget.DeviceDefault.Button.Borderless.Colored` requires API level 28 (current min is 21)"
+ errorLine1=" parent=&quot;@android:style/Widget.DeviceDefault.Button.Borderless.Colored&quot;>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/BarChartPreference/res/values/styles.xml"
+ line="35"
+ column="12"/>
+ </issue>
+
+</issues>
diff --git a/packages/SettingsLib/EmergencyNumber/lint-baseline.xml b/packages/SettingsLib/EmergencyNumber/lint-baseline.xml
new file mode 100644
index 000000000000..e9c687fd3227
--- /dev/null
+++ b/packages/SettingsLib/EmergencyNumber/lint-baseline.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+ errorLine1=" mTelephonyManager = context.getSystemService(TelephonyManager.class);"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/EmergencyNumber/src/com/android/settingslib/emergencynumber/EmergencyNumberUtils.java"
+ line="77"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+ errorLine1=" mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/EmergencyNumber/src/com/android/settingslib/emergencynumber/EmergencyNumberUtils.java"
+ line="78"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 23 (current min is 21): `android.telephony.CarrierConfigManager`"
+ errorLine1=" mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/EmergencyNumber/src/com/android/settingslib/emergencynumber/EmergencyNumberUtils.java"
+ line="78"
+ column="62"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 21): `android.telephony.TelephonyManager#getEmergencyNumberList`"
+ errorLine1=" Map&lt;Integer, List&lt;EmergencyNumber>> allLists = mTelephonyManager.getEmergencyNumberList("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/EmergencyNumber/src/com/android/settingslib/emergencynumber/EmergencyNumberUtils.java"
+ line="173"
+ column="74"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 21): `android.telephony.emergency.EmergencyNumber#getEmergencyNumberSources`"
+ errorLine1=" emergencyNumber.getEmergencyNumberSources().contains("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/EmergencyNumber/src/com/android/settingslib/emergencynumber/EmergencyNumberUtils.java"
+ line="196"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 24 (current min is 21): `android.telephony.SubscriptionManager#getDefaultSubscriptionId`"
+ errorLine1=" return promotedEmergencyNumberLists.get(SubscriptionManager.getDefaultSubscriptionId());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/EmergencyNumber/src/com/android/settingslib/emergencynumber/EmergencyNumberUtils.java"
+ line="219"
+ column="69"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 21): `android.telephony.emergency.EmergencyNumber#getNumber`"
+ errorLine1=" String number = emergencyNumber.getNumber();"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/EmergencyNumber/src/com/android/settingslib/emergencynumber/EmergencyNumberUtils.java"
+ line="234"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telephony.CarrierConfigManager#getConfigForSubId`"
+ errorLine1=" PersistableBundle b = carrierConfigManager.getConfigForSubId(subId);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/EmergencyNumber/src/com/android/settingslib/emergencynumber/EmergencyNumberUtils.java"
+ line="251"
+ column="52"/>
+ </issue>
+
+</issues>
diff --git a/packages/SettingsLib/HelpUtils/lint-baseline.xml b/packages/SettingsLib/HelpUtils/lint-baseline.xml
new file mode 100644
index 000000000000..940f027295a7
--- /dev/null
+++ b/packages/SettingsLib/HelpUtils/lint-baseline.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 21): `android.content.pm.PackageInfo#getLongVersionCode`"
+ errorLine1=" sCachedVersionCode = Long.toString(info.getLongVersionCode());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java"
+ line="239"
+ column="57"/>
+ </issue>
+
+</issues>
diff --git a/packages/SettingsLib/MainSwitchPreference/lint-baseline.xml b/packages/SettingsLib/MainSwitchPreference/lint-baseline.xml
new file mode 100644
index 000000000000..0ecf97952899
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/lint-baseline.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="`@android:id/switch_widget` requires API level 24 (current min is 21)"
+ errorLine1=" android:id=&quot;@android:id/switch_widget&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml"
+ line="49"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="`@android:style/Widget.Material.CompoundButton.Switch` requires API level 24 (current min is 21)"
+ errorLine1=" &lt;style name=&quot;Settings.MainSwitch&quot; parent=&quot;@android:style/Widget.Material.CompoundButton.Switch&quot;>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml"
+ line="24"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="`@android:style/Widget.Material.CompoundButton.Switch` requires API level 24 (current min is 21)"
+ errorLine1=" &lt;style name=&quot;Widget.SwitchBar.Switch&quot; parent=&quot;@android:style/Widget.Material.CompoundButton.Switch&quot;>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml"
+ line="28"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="`android:trackTint` requires API level 23 (current min is 21)"
+ errorLine1=" &lt;item name=&quot;android:trackTint&quot;>@color/switchbar_switch_track_tint&lt;/item>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml"
+ line="29"
+ column="15"/>
+ </issue>
+
+</issues>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/main_switch_bar.xml
new file mode 100644
index 000000000000..3ce9421f8e97
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/main_switch_bar.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:background="?android:attr/colorBackground"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:id="@+id/frame"
+ android:minHeight="@dimen/min_switch_bar_height"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:background="?android:attr/selectableItemBackground"
+ android:paddingLeft="@dimen/switchbar_margin_start"
+ android:paddingRight="@dimen/switchbar_margin_end">
+
+ <TextView
+ android:id="@+id/switch_text"
+ android:layout_height="wrap_content"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_marginRight="16dp"
+ android:layout_gravity="center_vertical"
+ android:maxLines="2"
+ android:ellipsize="end"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:textAlignment="viewStart"
+ style="@style/MainSwitchText" />
+
+ <ImageView
+ android:id="@+id/restricted_icon"
+ android:layout_width="@dimen/restricted_icon_size"
+ android:layout_height="@dimen/restricted_icon_size"
+ android:tint="?android:attr/colorAccent"
+ android:theme="@android:style/Theme.Material"
+ android:layout_gravity="center_vertical"
+ android:layout_marginEnd="@dimen/restricted_icon_margin_end"
+ android:src="@*android:drawable/ic_info"
+ android:visibility="gone" />
+
+ <Switch
+ android:id="@android:id/switch_widget"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:track="@drawable/track_selector"
+ android:thumb="@drawable/thumb_selector"
+ android:theme="@style/Settings.MainSwitch"/>
+ </LinearLayout>
+
+ <View
+ android:id="@+id/below_divider"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="?android:attr/listDivider" />
+</LinearLayout>
+
+
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml
index 85c01c5732ca..5dc320924da2 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (C) 2020 The Android Open Source Project
+ 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.
@@ -18,58 +18,40 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:background="?android:attr/colorBackground"
- android:orientation="vertical">
+ android:layout_width="match_parent">
- <LinearLayout
- android:id="@+id/frame"
- android:minHeight="@dimen/min_switch_bar_height"
+ <TextView
+ android:id="@+id/switch_text"
android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:background="?android:attr/selectableItemBackground"
- android:paddingLeft="@dimen/switchbar_margin_start"
- android:paddingRight="@dimen/switchbar_margin_end">
-
- <TextView
- android:id="@+id/switch_text"
- android:layout_height="wrap_content"
- android:layout_width="0dp"
- android:layout_weight="1"
- android:layout_marginRight="16dp"
- android:layout_gravity="center_vertical"
- android:maxLines="2"
- android:ellipsize="end"
- android:textAppearance="?android:attr/textAppearanceListItem"
- android:textAlignment="viewStart"
- style="@style/MainSwitchText" />
-
- <ImageView
- android:id="@+id/restricted_icon"
- android:layout_width="@dimen/restricted_icon_size"
- android:layout_height="@dimen/restricted_icon_size"
- android:tint="?android:attr/colorAccent"
- android:theme="@android:style/Theme.Material"
- android:layout_gravity="center_vertical"
- android:layout_marginEnd="@dimen/restricted_icon_margin_end"
- android:src="@*android:drawable/ic_info"
- android:visibility="gone" />
-
- <Switch
- android:id="@android:id/switch_widget"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:track="@drawable/track_selector"
- android:thumb="@drawable/thumb_selector"
- android:theme="@style/Settings.MainSwitch"/>
- </LinearLayout>
-
- <View
- android:id="@+id/below_divider"
- android:layout_width="match_parent"
- android:layout_height="1dp"
- android:background="?android:attr/listDivider" />
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_gravity="center_vertical"
+ android:maxLines="2"
+ android:ellipsize="end"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title"
+ android:textSize="16sp"
+ android:textColor="?android:attr/textColorPrimaryInverse"
+ android:layout_marginStart="@dimen/switchbar_subsettings_margin_start"
+ android:textAlignment="viewStart"/>
+
+ <ImageView
+ android:id="@+id/restricted_icon"
+ android:layout_width="@dimen/restricted_icon_size"
+ android:layout_height="@dimen/restricted_icon_size"
+ android:tint="?android:attr/colorAccent"
+ android:theme="@android:style/Theme.Material"
+ android:layout_gravity="center_vertical"
+ android:layout_marginEnd="@dimen/restricted_icon_margin_end"
+ android:src="@*android:drawable/ic_info"
+ android:visibility="gone"/>
+
+ <Switch
+ android:id="@android:id/switch_widget"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_marginEnd="@dimen/switchbar_subsettings_margin_end"
+ android:theme="@style/Widget.SwitchBar.Switch"/>
</LinearLayout>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml b/packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml
index 147db773fd05..e54569e9a814 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml
@@ -20,4 +20,6 @@
<color name="thumb_off">#BFFFFFFF</color>
<color name="track_off">@*android:color/material_grey_600</color>
+ <color name="switchbar_switch_track_tint">#82000000</color>
+ <color name="switchbar_switch_thumb_tint">@android:color/black</color>
</resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values-sw600dp/dmiens.xml b/packages/SettingsLib/MainSwitchPreference/res/values-sw600dp/dmiens.xml
new file mode 100644
index 000000000000..c6bb77ddad7d
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/values-sw600dp/dmiens.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- SwitchBar sub settings margin start / end -->
+ <dimen name="switchbar_subsettings_margin_start">80dp</dimen>
+</resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values-sw720dp-land/dmiens.xml b/packages/SettingsLib/MainSwitchPreference/res/values-sw720dp-land/dmiens.xml
new file mode 100644
index 000000000000..3e941c22f52b
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/values-sw720dp-land/dmiens.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- SwitchBar sub settings margin start / end -->
+ <dimen name="switchbar_subsettings_margin_start">128dp</dimen>
+ <dimen name="switchbar_subsettings_margin_end">128dp</dimen>
+</resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values-sw720dp/dmiens.xml b/packages/SettingsLib/MainSwitchPreference/res/values-sw720dp/dmiens.xml
new file mode 100644
index 000000000000..2f040daf0d7a
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/values-sw720dp/dmiens.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- SwitchBar sub settings margin start / end -->
+ <dimen name="switchbar_subsettings_margin_start">80dp</dimen>
+ <dimen name="switchbar_subsettings_margin_end">80dp</dimen>
+</resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/colors.xml b/packages/SettingsLib/MainSwitchPreference/res/values/colors.xml
index 147db773fd05..b5a73b17ed34 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values/colors.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values/colors.xml
@@ -20,4 +20,7 @@
<color name="thumb_off">#BFFFFFFF</color>
<color name="track_off">@*android:color/material_grey_600</color>
+ <color name="switchbar_background_color">@*android:color/material_grey_600</color>
+ <color name="switchbar_switch_track_tint">#BFFFFFFF</color>
+ <color name="switchbar_switch_thumb_tint">@android:color/white</color>
</resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml b/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
index b145c9bc4b39..c471bcd645a6 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
@@ -34,4 +34,8 @@
<!-- Restricted icon in switch bar -->
<dimen name="restricted_icon_margin_end">16dp</dimen>
+
+ <!-- SwitchBar sub settings margin start / end -->
+ <dimen name="switchbar_subsettings_margin_start">72dp</dimen>
+ <dimen name="switchbar_subsettings_margin_end">16dp</dimen>
</resources>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml b/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml
index 59b5899a4173..e05809799865 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml
@@ -25,4 +25,10 @@
<item name="android:switchMinWidth">@dimen/min_switch_width</item>
</style>
+ <style name="Widget.SwitchBar.Switch" parent="@android:style/Widget.Material.CompoundButton.Switch">
+ <item name="android:trackTint">@color/switchbar_switch_track_tint</item>
+ <item name="android:thumbTint">@color/switchbar_switch_thumb_tint</item>
+ <item name="android:minHeight">48dp</item>
+ <item name="android:minWidth">48dp</item>
+ </style>
</resources>
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 ae9261c48419..2be3f0d815aa 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
@@ -28,7 +28,8 @@ import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.TextView;
-import androidx.core.content.res.TypedArrayUtils;
+import androidx.annotation.ColorInt;
+import androidx.core.os.BuildCompat;
import java.util.ArrayList;
import java.util.List;
@@ -42,8 +43,11 @@ public class MainSwitchBar extends LinearLayout implements CompoundButton.OnChec
private final List<OnMainSwitchChangeListener> mSwitchChangeListeners = new ArrayList<>();
- private View mAboveDivider;
- private View mBelowDivider;
+ @ColorInt
+ private int mBackgroundColor;
+ @ColorInt
+ private int mBackgroundActivatedColor;
+
protected TextView mTextView;
protected Switch mSwitch;
@@ -66,6 +70,14 @@ public class MainSwitchBar extends LinearLayout implements CompoundButton.OnChec
LayoutInflater.from(context).inflate(resourceId(context, "layout", "main_switch_bar"),
this);
+ if (!BuildCompat.isAtLeastS()) {
+ final TypedArray a = context.obtainStyledAttributes(
+ new int[]{android.R.attr.colorAccent});
+ mBackgroundActivatedColor = a.getColor(0, 0);
+ mBackgroundColor = context.getColor(R.color.switchbar_background_color);
+ a.recycle();
+ }
+
setFocusable(true);
setClickable(true);
@@ -80,12 +92,13 @@ public class MainSwitchBar extends LinearLayout implements CompoundButton.OnChec
final 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,
+ final CharSequence title = a.getText(
androidx.preference.R.styleable.Preference_android_title);
setTitle(title);
a.recycle();
}
+
+ setBackground(true);
}
@Override
@@ -105,6 +118,7 @@ public class MainSwitchBar extends LinearLayout implements CompoundButton.OnChec
if (mSwitch != null) {
mSwitch.setChecked(checked);
}
+ setBackground(checked);
}
/**
@@ -189,6 +203,14 @@ public class MainSwitchBar extends LinearLayout implements CompoundButton.OnChec
}
}
+ private void setBackground(boolean checked) {
+ if (BuildCompat.isAtLeastS()) {
+ return;
+ }
+
+ setBackgroundColor(checked ? mBackgroundActivatedColor : mBackgroundColor);
+ }
+
static class SavedState extends BaseSavedState {
boolean mChecked;
boolean mVisible;
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 ebeffcc3c361..1f7f8d44d610 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
@@ -20,7 +20,6 @@ import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
-import androidx.core.content.res.TypedArrayUtils;
import androidx.preference.PreferenceViewHolder;
import androidx.preference.TwoStatePreference;
@@ -79,8 +78,7 @@ public class MainSwitchPreference extends TwoStatePreference {
final 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,
+ final CharSequence title = a.getText(
androidx.preference.R.styleable.Preference_android_title);
setTitle(title);
a.recycle();
diff --git a/packages/SettingsLib/ProgressBar/lint-baseline.xml b/packages/SettingsLib/ProgressBar/lint-baseline.xml
new file mode 100644
index 000000000000..03d0f3f43986
--- /dev/null
+++ b/packages/SettingsLib/ProgressBar/lint-baseline.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="`?android:attr/colorSecondary` requires API level 25 (current min is 21)"
+ errorLine1=" android:background=&quot;?android:attr/colorSecondary&quot; />"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/ProgressBar/res/layout/progress_header.xml"
+ line="27"
+ column="9"/>
+ </issue>
+
+</issues>
diff --git a/packages/SettingsLib/RestrictedLockUtils/lint-baseline.xml b/packages/SettingsLib/RestrictedLockUtils/lint-baseline.xml
new file mode 100644
index 000000000000..173c7353ae8c
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/lint-baseline.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+ errorLine1=" ComponentName adminComponent = userContext.getSystemService("
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java"
+ line="59"
+ column="52"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+ errorLine1=" UserManager um = context.getSystemService(UserManager.class);"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java"
+ line="101"
+ column="34"/>
+ </issue>
+
+</issues>
diff --git a/packages/SettingsLib/SettingsSpinner/lint-baseline.xml b/packages/SettingsLib/SettingsSpinner/lint-baseline.xml
new file mode 100644
index 000000000000..ae1ed38e9288
--- /dev/null
+++ b/packages/SettingsLib/SettingsSpinner/lint-baseline.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `new android.widget.Spinner`"
+ errorLine1=" super(context, attrs, defStyleAttr, defStyleRes, mode, null);"
+ errorLine2=" ~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java"
+ line="122"
+ column="9"/>
+ </issue>
+
+</issues>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/dimens.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/dimens.xml
index 17b68050a3cc..d092666f972c 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v31/dimens.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v31/dimens.xml
@@ -19,7 +19,7 @@
<dimen name="preference_title_font_size">20sp</dimen>
<dimen name="icon_min_width">48dp</dimen>
<dimen name="preference_padding_start">24dp</dimen>
- <dimen name="preference_padding_end">24dp</dimen>
+ <dimen name="preference_padding_end">16dp</dimen>
<dimen name="app_preference_padding_start">20dp</dimen>
<dimen name="app_icon_min_width">52dp</dimen>
</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml b/packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml
index 17596ac2903a..dcbdc07d1335 100644
--- a/packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<resources>
+ <!--DEPRECATED. It will remove after all of client team migrated to new style. -->
<style name="PreferenceTheme" parent="@style/PreferenceThemeOverlay">
<item name="preferenceCategoryStyle">@style/SettingsCategoryPreference</item>
<item name="preferenceStyle">@style/SettingsPreference</item>
@@ -27,6 +28,18 @@
<item name="footerPreferenceStyle">@style/Preference.Material</item>
</style>
+ <style name="SettingsPreferenceTheme" parent="@style/PreferenceThemeOverlay">
+ <item name="preferenceCategoryStyle">@style/SettingsCategoryPreference</item>
+ <item name="preferenceStyle">@style/SettingsPreference</item>
+ <item name="checkBoxPreferenceStyle">@style/SettingsCheckBoxPreference</item>
+ <item name="dialogPreferenceStyle">@style/SettingsPreference</item>
+ <item name="editTextPreferenceStyle">@style/SettingsEditTextPreference</item>
+ <item name="dropdownPreferenceStyle">@style/SettingsDropdownPreference</item>
+ <item name="switchPreferenceStyle">@style/SettingsSwitchPreference</item>
+ <item name="seekBarPreferenceStyle">@style/SettingsSeekbarPreference</item>
+ <item name="footerPreferenceStyle">@style/Preference.Material</item>
+ </style>
+
<style name="SettingsCategoryPreference" parent="@style/Preference.Category.Material">
<item name="iconSpaceReserved">@bool/config_icon_space_reserved</item>
<item name="allowDividerAbove">@bool/config_allow_divider</item>
diff --git a/packages/SettingsLib/SettingsTheme/res/values/themes.xml b/packages/SettingsLib/SettingsTheme/res/values/themes.xml
index 36ca684a14a3..13c7523317fe 100644
--- a/packages/SettingsLib/SettingsTheme/res/values/themes.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values/themes.xml
@@ -21,7 +21,7 @@
<item name="android:textAppearanceListItem">@style/TextAppearance.PreferenceTitle</item>
<item name="android:listPreferredItemPaddingStart">@dimen/preference_padding_start</item>
<item name="android:listPreferredItemPaddingEnd">@dimen/preference_padding_end</item>
- <item name="preferenceTheme">@style/PreferenceTheme</item>
+ <item name="preferenceTheme">@style/SettingsPreferenceTheme</item>
</style>
<!-- Using in SubSettings page including injected settings page -->
diff --git a/packages/SettingsLib/Tile/lint-baseline.xml b/packages/SettingsLib/Tile/lint-baseline.xml
new file mode 100644
index 000000000000..4df6bd958f36
--- /dev/null
+++ b/packages/SettingsLib/Tile/lint-baseline.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 24 (current min is 21): `java.lang.Iterable#forEach`"
+ errorLine1=" controllers.forEach(controller -> {"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/SwitchesProvider.java"
+ line="79"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 21): `android.os.Parcel#readBoolean`"
+ errorLine1=" final boolean isProviderTile = in.readBoolean();"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java"
+ line="83"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 21): `android.os.Parcel#writeBoolean`"
+ errorLine1=" dest.writeBoolean(this instanceof ProviderTile);"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java"
+ line="102"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Icon#createWithResource`"
+ errorLine1=" final Icon icon = Icon.createWithResource(componentInfo.packageName, iconResId);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java"
+ line="314"
+ column="36"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Icon#setTint`"
+ errorLine1=" icon.setTint(tintColor);"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java"
+ line="320"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 21): `android.os.Parcel#readBoolean`"
+ errorLine1=" final boolean isProviderTile = source.readBoolean();"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java"
+ line="364"
+ column="51"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 21): `android.content.Context#getAttributionSource`"
+ errorLine1=" return provider.call(context.getAttributionSource(),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java"
+ line="558"
+ column="42"/>
+ </issue>
+
+</issues>
diff --git a/packages/SettingsLib/Utils/lint-baseline.xml b/packages/SettingsLib/Utils/lint-baseline.xml
new file mode 100644
index 000000000000..172bde3df541
--- /dev/null
+++ b/packages/SettingsLib/Utils/lint-baseline.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+ errorLine1=" return context.getSystemService(UserManager.class).isManagedProfile(userId)"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/Utils/src/com/android/settingslib/utils/applications/AppUtils.java"
+ line="58"
+ column="24"/>
+ </issue>
+
+</issues>
diff --git a/packages/SettingsLib/lint-baseline.xml b/packages/SettingsLib/lint-baseline.xml
new file mode 100644
index 000000000000..f6d6ca62e78c
--- /dev/null
+++ b/packages/SettingsLib/lint-baseline.xml
@@ -0,0 +1,895 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.telephony.ims.ImsMmTelManager#getRegistrationState`"
+ errorLine1=" imsMmTelManager.getRegistrationState(executors, stateCallback);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java"
+ line="116"
+ column="29"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.wifi.hotspot2.PasspointConfiguration#getUniqueId`"
+ errorLine1=" mPasspointUniqueId = config.getUniqueId();"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+ line="379"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.wifi.hotspot2.PasspointConfiguration#getSubscriptionExpirationTimeMillis`"
+ errorLine1=" mSubscriptionExpirationTimeInMillis = config.getSubscriptionExpirationTimeMillis();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+ line="382"
+ column="54"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.wifi.hotspot2.PasspointConfiguration#isOsuProvisioned`"
+ errorLine1=" if (config.isOsuProvisioned()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+ line="383"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.wifi.WifiConfiguration#getKey`"
+ errorLine1=" mPasspointUniqueId = config.getKey();"
+ errorLine2=" ~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+ line="400"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.wifi.WifiManager#calculateSignalLevel`"
+ errorLine1=" int difference = wifiManager.calculateSignalLevel(other.mRssi)"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+ line="481"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.wifi.WifiManager#calculateSignalLevel`"
+ errorLine1=" - wifiManager.calculateSignalLevel(mRssi);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+ line="482"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.wifi.WifiConfiguration#getKey`"
+ errorLine1=" return getKey(config.getKey());"
+ errorLine2=" ~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+ line="707"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.wifi.WifiConfiguration#getKey`"
+ errorLine1=" return (isPasspoint() &amp;&amp; config.getKey().equals(mConfig.getKey()));"
+ errorLine2=" ~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+ line="796"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.wifi.WifiConfiguration#getKey`"
+ errorLine1=" return (isPasspoint() &amp;&amp; config.getKey().equals(mConfig.getKey()));"
+ errorLine2=" ~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+ line="796"
+ column="69"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.wifi.WifiManager#calculateSignalLevel`"
+ errorLine1=" return getWifiManager().calculateSignalLevel(mRssi);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+ line="903"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.wifi.hotspot2.PasspointConfiguration#getUniqueId`"
+ errorLine1=" String uniqueId = passpointConfig.getUniqueId();"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+ line="1988"
+ column="47"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.wifi.WifiConfiguration#getKey`"
+ errorLine1=" if (TextUtils.equals(config.getKey(), uniqueId)) {"
+ errorLine2=" ~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+ line="1992"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.util.SparseArray#contains`"
+ errorLine1=" return mEntriesMap.contains(userId);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+ line="1503"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.bluetooth.BluetoothDevice#getAlias`"
+ errorLine1=" + mDevice.getAlias() + &quot;, newProfileState &quot; + newProfileState);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java"
+ line="155"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.bluetooth.BluetoothDevice#getAlias`"
+ errorLine1=" final String aliasName = mDevice.getAlias();"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java"
+ line="431"
+ column="42"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 29): `android.bluetooth.BluetoothDevice#setAlias`"
+ errorLine1=" mDevice.setAlias(name);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java"
+ line="442"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.bluetooth.BluetoothDevice#getAlias`"
+ errorLine1=" return !TextUtils.isEmpty(mDevice.getAlias());"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java"
+ line="489"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.bluetooth.BluetoothDevice#getAlias`"
+ errorLine1=" Log.d(TAG, &quot;updating profiles for &quot; + mDevice.getAlias());"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java"
+ line="638"
+ column="59"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.bluetooth.BluetoothDevice#getAlias`"
+ errorLine1=" String name = device.getAlias();"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java"
+ line="171"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 29): `android.net.wifi.WifiManager.SubsystemRestartTrackingCallback`"
+ errorLine1=" new SubsystemRestartTrackingCallback() {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/connectivity/ConnectivitySubsystemsRecoveryManager.java"
+ line="62"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 29): `android.telephony.TelephonyCallback`"
+ errorLine1=" private class MobileTelephonyCallback extends TelephonyCallback implements"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/connectivity/ConnectivitySubsystemsRecoveryManager.java"
+ line="77"
+ column="51"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 29): `android.net.wifi.WifiManager#registerSubsystemRestartTrackingCallback`"
+ errorLine1=" mWifiManager.registerSubsystemRestartTrackingCallback(new HandlerExecutor(mHandler),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/connectivity/ConnectivitySubsystemsRecoveryManager.java"
+ line="197"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 29): `android.net.wifi.WifiManager#unregisterSubsystemRestartTrackingCallback`"
+ errorLine1=" mWifiManager.unregisterSubsystemRestartTrackingCallback("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/connectivity/ConnectivitySubsystemsRecoveryManager.java"
+ line="202"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 29): `android.telephony.TelephonyManager#registerTelephonyCallback`"
+ errorLine1=" mTelephonyManager.registerTelephonyCallback(new HandlerExecutor(mHandler),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/connectivity/ConnectivitySubsystemsRecoveryManager.java"
+ line="207"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 29): `android.telephony.TelephonyManager#unregisterTelephonyCallback`"
+ errorLine1=" mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/connectivity/ConnectivitySubsystemsRecoveryManager.java"
+ line="212"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 29): `android.telephony.TelephonyManager#isDataCapable`"
+ errorLine1=" return getTelephonyManager().isDataCapable()"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+ line="236"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.telephony.TelephonyManager#getSubscriptionId`"
+ errorLine1=" final int mobileDefaultSubId = telephonyManager.getSubscriptionId();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java"
+ line="41"
+ column="57"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getName`"
+ errorLine1=" return mRouteInfo.getName().toString();"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java"
+ line="51"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getClientPackageName`"
+ errorLine1=" return mRouteInfo.getClientPackageName() != null"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java"
+ line="56"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getFeatures`"
+ errorLine1=" final List&lt;String> features = mRouteInfo.getFeatures();"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java"
+ line="93"
+ column="50"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getId`"
+ errorLine1=" if (info != null &amp;&amp; info.getSelectableRoutes().contains(device.mRouteInfo.getId())) {"
+ errorLine2=" ~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="131"
+ column="83"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.RoutingSessionInfo#getSelectableRoutes`"
+ errorLine1=" if (info != null &amp;&amp; info.getSelectableRoutes().contains(device.mRouteInfo.getId())) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="131"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getId`"
+ errorLine1=" if (info != null &amp;&amp; info.getSelectedRoutes().contains(device.mRouteInfo.getId())) {"
+ errorLine2=" ~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="162"
+ column="81"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.RoutingSessionInfo#getSelectedRoutes`"
+ errorLine1=" if (info != null &amp;&amp; info.getSelectedRoutes().contains(device.mRouteInfo.getId())) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="162"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getName`"
+ errorLine1=" Log.d(TAG, route.getName() + &quot; is deselectable for &quot; + mPackageName);"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="238"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.RoutingSessionInfo#getVolumeMax`"
+ errorLine1=" return info.getVolumeMax();"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="320"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.RoutingSessionInfo#getVolume`"
+ errorLine1=" return info.getVolume();"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="341"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.RoutingSessionInfo#getName`"
+ errorLine1=" return info.getName();"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="357"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getName`"
+ errorLine1=" Log.d(TAG, &quot;buildAllRoutes() route : &quot; + route.getName() + &quot;, volume : &quot;"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="408"
+ column="64"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getVolume`"
+ errorLine1=" + route.getVolume() + &quot;, type : &quot; + route.getType());"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="409"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#isSystemRoute`"
+ errorLine1=" if (route.isSystemRoute()) {"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="411"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getName`"
+ errorLine1=" Log.d(TAG, &quot;buildAvailableRoutes() route : &quot; + route.getName() + &quot;, volume : &quot;"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="424"
+ column="70"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getVolume`"
+ errorLine1=" + route.getVolume() + &quot;, type : &quot; + route.getType());"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="425"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getId`"
+ errorLine1=" &amp;&amp; getRoutingSessionInfo().getSelectedRoutes().contains(route.getId())"
+ errorLine2=" ~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="444"
+ column="87"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.RoutingSessionInfo#getSelectedRoutes`"
+ errorLine1=" &amp;&amp; getRoutingSessionInfo().getSelectedRoutes().contains(route.getId())"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="444"
+ column="52"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.RoutingSessionInfo#getName`"
+ errorLine1=" Log.d(TAG, &quot;onTransferred() oldSession : &quot; + oldSession.getName()"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="509"
+ column="73"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.RoutingSessionInfo#getName`"
+ errorLine1=" + &quot;, newSession : &quot; + newSession.getName());"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+ line="510"
+ column="58"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.RoutingSessionInfo#getId`"
+ errorLine1=" if (TextUtils.equals(sessionId, info.getId())) {"
+ errorLine2=" ~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java"
+ line="342"
+ column="50"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getVolumeMax`"
+ errorLine1=" return mRouteInfo.getVolumeMax();"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java"
+ line="221"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getVolume`"
+ errorLine1=" return mRouteInfo.getVolume();"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java"
+ line="234"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getClientPackageName`"
+ errorLine1=" return mRouteInfo.getClientPackageName();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java"
+ line="247"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getFeatures`"
+ errorLine1=" return mRouteInfo.getFeatures();"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java"
+ line="387"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getId`"
+ errorLine1=" return route.getId();"
+ errorLine2=" ~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java"
+ line="57"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.telephony.TelephonyDisplayInfo#getOverrideNetworkType`"
+ errorLine1=" if (telephonyDisplayInfo.getOverrideNetworkType()"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/mobile/MobileMappings.java"
+ line="42"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.telephony.TelephonyDisplayInfo#getNetworkType`"
+ errorLine1=" return toIconKey(telephonyDisplayInfo.getNetworkType());"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/mobile/MobileMappings.java"
+ line="44"
+ column="51"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.telephony.TelephonyDisplayInfo#getOverrideNetworkType`"
+ errorLine1=" return toDisplayIconKey(telephonyDisplayInfo.getOverrideNetworkType());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/mobile/MobileMappings.java"
+ line="46"
+ column="58"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 29): `android.telephony.TelephonyManager#registerTelephonyCallback`"
+ errorLine1=" mPhone.registerTelephonyCallback(mReceiverHandler::post, mTelephonyCallback);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/mobile/MobileStatusTracker.java"
+ line="80"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 29): `android.telephony.TelephonyManager#unregisterTelephonyCallback`"
+ errorLine1=" mPhone.unregisterTelephonyCallback(mTelephonyCallback);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/mobile/MobileStatusTracker.java"
+ line="82"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 29): `android.telephony.TelephonyCallback`"
+ errorLine1=" public class MobileTelephonyCallback extends TelephonyCallback implements"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/mobile/MobileStatusTracker.java"
+ line="109"
+ column="50"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 29): `android.telephony.TelephonyCallback.ServiceStateListener`"
+ errorLine1=" TelephonyCallback.ServiceStateListener,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/mobile/MobileStatusTracker.java"
+ line="110"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 29): `android.telephony.TelephonyCallback.SignalStrengthsListener`"
+ errorLine1=" TelephonyCallback.SignalStrengthsListener,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/mobile/MobileStatusTracker.java"
+ line="111"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 29): `android.telephony.TelephonyCallback.DataConnectionStateListener`"
+ errorLine1=" TelephonyCallback.DataConnectionStateListener,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/mobile/MobileStatusTracker.java"
+ line="112"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 29): `android.telephony.TelephonyCallback.DataActivityListener`"
+ errorLine1=" TelephonyCallback.DataActivityListener,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/mobile/MobileStatusTracker.java"
+ line="113"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 29): `android.telephony.TelephonyCallback.CarrierNetworkListener`"
+ errorLine1=" TelephonyCallback.CarrierNetworkListener,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/mobile/MobileStatusTracker.java"
+ line="114"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 29): `android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener`"
+ errorLine1=" TelephonyCallback.ActiveDataSubscriptionIdListener,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/mobile/MobileStatusTracker.java"
+ line="115"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 29): `android.telephony.TelephonyCallback.DisplayInfoListener`"
+ errorLine1=" TelephonyCallback.DisplayInfoListener{"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/mobile/MobileStatusTracker.java"
+ line="116"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.telephony.SubscriptionManager#getActiveDataSubscriptionId`"
+ errorLine1=" return SubscriptionManager.getActiveDataSubscriptionId();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/mobile/MobileStatusTracker.java"
+ line="207"
+ column="40"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 29): `com.google.android.collect.Lists#newArrayList`"
+ errorLine1=" private ArrayList&lt;NetworkPolicy> mPolicies = Lists.newArrayList();"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java"
+ line="54"
+ column="56"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.media.MediaRoute2Info#getName`"
+ errorLine1=" name = mRouteInfo.getName();"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java"
+ line="71"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.app.admin.DevicePolicyManager#isOrganizationOwnedDeviceWithManagedProfile`"
+ errorLine1=" if (profileAdmin != null &amp;&amp; dpm.isOrganizationOwnedDeviceWithManagedProfile()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java"
+ line="280"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.content.Context#bindServiceAsUser`"
+ errorLine1=" mContext.bindServiceAsUser(mServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionController.java"
+ line="83"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `new android.net.NetworkInfo`"
+ errorLine1=" mNetworkInfo = new NetworkInfo("
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java"
+ line="110"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.wifi.WifiManager#getMaxSignalLevel`"
+ errorLine1=" int maxSignalLevel = wifiManager.getMaxSignalLevel();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java"
+ line="131"
+ column="42"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 29): `android.telephony.TelephonyManager#isDataCapable`"
+ errorLine1=" return !context.getSystemService(TelephonyManager.class).isDataCapable();"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/Utils.java"
+ line="447"
+ column="66"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.NetworkRequest.Builder#clearCapabilities`"
+ errorLine1=" .clearCapabilities()"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java"
+ line="72"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 29): `android.net.wifi.WifiInfo#getSubscriptionId`"
+ errorLine1=" subId = mWifiInfo.getSubscriptionId();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java"
+ line="231"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 29): `android.net.wifi.WifiInfo#getSubscriptionId`"
+ errorLine1=" subId = mWifiInfo.getSubscriptionId();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java"
+ line="263"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.wifi.WifiManager#calculateSignalLevel`"
+ errorLine1=" level = mWifiManager.calculateSignalLevel(rssi);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java"
+ line="279"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.NetworkRequest.Builder#clearCapabilities`"
+ errorLine1=" .clearCapabilities()"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java"
+ line="243"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 29): `android.net.wifi.WifiInfo#getWifiStandard`"
+ errorLine1=" visibility.append(&quot; standard = &quot;).append(info.getWifiStandard());"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java"
+ line="104"
+ column="59"/>
+ </issue>
+
+</issues>
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
index 46ecbd45a860..cb41743a02e4 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
@@ -694,6 +694,16 @@ public class AccessPointTest {
assertThat(ap.getTitle()).isEqualTo(providerFriendlyName);
}
+ // This method doesn't copy mIsFailover, mIsAvailable and mIsRoaming because NetworkInfo
+ // doesn't expose those three set methods. But that's fine since the tests don't use those three
+ // variables.
+ private NetworkInfo copyNetworkInfo(NetworkInfo ni) {
+ final NetworkInfo copy = new NetworkInfo(ni.getType(), ni.getSubtype(), ni.getTypeName(),
+ ni.getSubtypeName());
+ copy.setDetailedState(ni.getDetailedState(), ni.getReason(), ni.getExtraInfo());
+ return copy;
+ }
+
@Test
public void testUpdateNetworkInfo_returnsTrue() {
int networkId = 123;
@@ -715,7 +725,7 @@ public class AccessPointTest {
.setWifiInfo(wifiInfo)
.build();
- NetworkInfo newInfo = new NetworkInfo(networkInfo);
+ NetworkInfo newInfo = copyNetworkInfo(networkInfo);
newInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", "");
assertThat(ap.update(config, wifiInfo, newInfo)).isTrue();
}
@@ -741,7 +751,7 @@ public class AccessPointTest {
.setWifiInfo(wifiInfo)
.build();
- NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
+ NetworkInfo newInfo = copyNetworkInfo(networkInfo); // same values
assertThat(ap.update(config, wifiInfo, newInfo)).isFalse();
}
@@ -766,7 +776,7 @@ public class AccessPointTest {
.setWifiInfo(wifiInfo)
.build();
- NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
+ NetworkInfo newInfo = copyNetworkInfo(networkInfo); // same values
wifiInfo.setRssi(rssi + 1);
assertThat(ap.update(config, wifiInfo, newInfo)).isTrue();
}
@@ -792,7 +802,7 @@ public class AccessPointTest {
.setWifiInfo(wifiInfo)
.build();
- NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
+ NetworkInfo newInfo = copyNetworkInfo(networkInfo); // same values
wifiInfo.setRssi(WifiInfo.INVALID_RSSI);
assertThat(ap.update(config, wifiInfo, newInfo)).isFalse();
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index 0790189cb85d..97032dd41801 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -127,6 +127,7 @@ public class GlobalSettingsValidators {
VALIDATORS.put(Global.POWER_BUTTON_LONG_PRESS, new InclusiveIntegerRangeValidator(0, 5));
VALIDATORS.put(
Global.POWER_BUTTON_VERY_LONG_PRESS, new InclusiveIntegerRangeValidator(0, 1));
+ VALIDATORS.put(Global.KEY_CHORD_POWER_VOLUME_UP, new InclusiveIntegerRangeValidator(0, 2));
VALIDATORS.put(Global.NOTIFICATION_BUBBLES, BOOLEAN_VALIDATOR);
VALIDATORS.put(Global.CUSTOM_BUGREPORT_HANDLER_APP, ANY_STRING_VALIDATOR);
VALIDATORS.put(Global.CUSTOM_BUGREPORT_HANDLER_USER, ANY_INTEGER_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 6440d2a53f84..91667c4e88c7 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -16,6 +16,7 @@
package com.android.providers.settings;
+import static android.os.Process.INVALID_UID;
import static android.os.Process.ROOT_UID;
import static android.os.Process.SHELL_UID;
import static android.os.Process.SYSTEM_UID;
@@ -363,11 +364,6 @@ public class SettingsProvider extends ContentProvider {
mHandler = new Handler(mHandlerThread.getLooper());
mSettingsRegistry = new SettingsRegistry();
}
- SettingsState.cacheSystemPackageNamesAndSystemSignature(getContext());
- synchronized (mLock) {
- mSettingsRegistry.migrateAllLegacySettingsIfNeededLocked();
- mSettingsRegistry.syncSsaidTableOnStartLocked();
- }
mHandler.post(() -> {
registerBroadcastReceivers();
startWatchingUserRestrictionChanges();
@@ -2503,6 +2499,8 @@ public class SettingsProvider extends ContentProvider {
mHandler = new MyHandler(getContext().getMainLooper());
mGenerationRegistry = new GenerationRegistry(mLock);
mBackupManager = new BackupManager(getContext());
+ migrateAllLegacySettingsIfNeeded();
+ syncSsaidTableOnStart();
}
private void generateUserKeyLocked(int userId) {
@@ -2589,36 +2587,38 @@ public class SettingsProvider extends ContentProvider {
return getSettingLocked(SETTINGS_TYPE_SSAID, userId, uid);
}
- private void syncSsaidTableOnStartLocked() {
- // Verify that each user's packages and ssaid's are in sync.
- for (UserInfo user : mUserManager.getAliveUsers()) {
- // Get all uids for the user's packages.
- final List<PackageInfo> packages;
- try {
- packages = mPackageManager.getInstalledPackages(
+ public void syncSsaidTableOnStart() {
+ synchronized (mLock) {
+ // Verify that each user's packages and ssaid's are in sync.
+ for (UserInfo user : mUserManager.getAliveUsers()) {
+ // Get all uids for the user's packages.
+ final List<PackageInfo> packages;
+ try {
+ packages = mPackageManager.getInstalledPackages(
PackageManager.MATCH_UNINSTALLED_PACKAGES,
user.id).getList();
- } catch (RemoteException e) {
- throw new IllegalStateException("Package manager not available");
- }
- final Set<String> appUids = new HashSet<>();
- for (PackageInfo info : packages) {
- appUids.add(Integer.toString(info.applicationInfo.uid));
- }
+ } catch (RemoteException e) {
+ throw new IllegalStateException("Package manager not available");
+ }
+ final Set<String> appUids = new HashSet<>();
+ for (PackageInfo info : packages) {
+ appUids.add(Integer.toString(info.applicationInfo.uid));
+ }
- // Get all uids currently stored in the user's ssaid table.
- final Set<String> ssaidUids = new HashSet<>(
- getSettingsNamesLocked(SETTINGS_TYPE_SSAID, user.id));
- ssaidUids.remove(SSAID_USER_KEY);
+ // Get all uids currently stored in the user's ssaid table.
+ final Set<String> ssaidUids = new HashSet<>(
+ getSettingsNamesLocked(SETTINGS_TYPE_SSAID, user.id));
+ ssaidUids.remove(SSAID_USER_KEY);
- // Perform a set difference for the appUids and ssaidUids.
- ssaidUids.removeAll(appUids);
+ // Perform a set difference for the appUids and ssaidUids.
+ ssaidUids.removeAll(appUids);
- // If there are ssaidUids left over they need to be removed from the table.
- final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID,
- user.id);
- for (String uid : ssaidUids) {
- ssaidSettings.deleteSettingLocked(uid);
+ // If there are ssaidUids left over they need to be removed from the table.
+ final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID,
+ user.id);
+ for (String uid : ssaidUids) {
+ ssaidSettings.deleteSettingLocked(uid);
+ }
}
}
}
@@ -2911,7 +2911,7 @@ public class SettingsProvider extends ContentProvider {
boolean someSettingChanged = false;
Setting setting = settingsState.getSettingLocked(name);
if (!SettingsState.isSystemPackage(getContext(),
- setting.getPackageName())) {
+ setting.getPackageName(), INVALID_UID, userId)) {
if (prefix != null && !setting.getName().startsWith(prefix)) {
continue;
}
@@ -2931,7 +2931,7 @@ public class SettingsProvider extends ContentProvider {
boolean someSettingChanged = false;
Setting setting = settingsState.getSettingLocked(name);
if (!SettingsState.isSystemPackage(getContext(),
- setting.getPackageName())) {
+ setting.getPackageName(), INVALID_UID, userId)) {
if (prefix != null && !setting.getName().startsWith(prefix)) {
continue;
}
@@ -3009,38 +3009,40 @@ public class SettingsProvider extends ContentProvider {
return mSettingsStates.get(key);
}
- private void migrateAllLegacySettingsIfNeededLocked() {
- final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
- File globalFile = getSettingsFile(key);
- if (SettingsState.stateFileExists(globalFile)) {
- return;
- }
+ private void migrateAllLegacySettingsIfNeeded() {
+ synchronized (mLock) {
+ final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
+ File globalFile = getSettingsFile(key);
+ if (SettingsState.stateFileExists(globalFile)) {
+ return;
+ }
- mSettingsCreationBuildId = Build.ID;
+ mSettingsCreationBuildId = Build.ID;
- final long identity = Binder.clearCallingIdentity();
- try {
- List<UserInfo> users = mUserManager.getAliveUsers();
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ List<UserInfo> users = mUserManager.getAliveUsers();
- final int userCount = users.size();
- for (int i = 0; i < userCount; i++) {
- final int userId = users.get(i).id;
+ final int userCount = users.size();
+ for (int i = 0; i < userCount; i++) {
+ final int userId = users.get(i).id;
- DatabaseHelper dbHelper = new DatabaseHelper(getContext(), userId);
- SQLiteDatabase database = dbHelper.getWritableDatabase();
- migrateLegacySettingsForUserLocked(dbHelper, database, userId);
+ DatabaseHelper dbHelper = new DatabaseHelper(getContext(), userId);
+ SQLiteDatabase database = dbHelper.getWritableDatabase();
+ migrateLegacySettingsForUserLocked(dbHelper, database, userId);
- // Upgrade to the latest version.
- UpgradeController upgrader = new UpgradeController(userId);
- upgrader.upgradeIfNeededLocked();
+ // Upgrade to the latest version.
+ UpgradeController upgrader = new UpgradeController(userId);
+ upgrader.upgradeIfNeededLocked();
- // Drop from memory if not a running user.
- if (!mUserManager.isUserRunning(new UserHandle(userId))) {
- removeUserStateLocked(userId, false);
+ // Drop from memory if not a running user.
+ if (!mUserManager.isUserRunning(new UserHandle(userId))) {
+ removeUserStateLocked(userId, false);
+ }
}
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
- } finally {
- Binder.restoreCallingIdentity(identity);
}
}
@@ -5034,9 +5036,19 @@ public class SettingsProvider extends ContentProvider {
// In the upgrade case we pretend the call is made from the app
// that made the last change to the setting to properly determine
// whether the call has been made by a system component.
+ int callingUid = -1;
+ try {
+ callingUid = mPackageManager.getPackageUid(setting.getPackageName(), 0, userId);
+ } catch (RemoteException e) {
+ /* ignore - handled below */
+ }
+ if (callingUid < 0) {
+ Slog.e(LOG_TAG, "Unknown package: " + setting.getPackageName());
+ continue;
+ }
try {
- final boolean systemSet = SettingsState.isSystemPackage(
- getContext(), setting.getPackageName());
+ final boolean systemSet = SettingsState.isSystemPackage(getContext(),
+ setting.getPackageName(), callingUid, userId);
if (systemSet) {
settings.insertSettingOverrideableByRestoreLocked(name, setting.getValue(),
setting.getTag(), true, setting.getPackageName());
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 911ff9916d6c..53d868ac0050 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -17,13 +17,14 @@
package com.android.providers.settings;
import static android.os.Process.FIRST_APPLICATION_UID;
+import static android.os.Process.INVALID_UID;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.Signature;
import android.os.Binder;
import android.os.Build;
import android.os.FileUtils;
@@ -36,10 +37,10 @@ import android.provider.Settings;
import android.providers.settings.SettingsOperationProto;
import android.text.TextUtils;
import android.util.ArrayMap;
-import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.Base64;
import android.util.Slog;
+import android.util.SparseIntArray;
import android.util.TimeUtils;
import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
@@ -148,7 +149,13 @@ final class SettingsState {
private static final String NULL_VALUE = "null";
- private static final ArraySet<String> sSystemPackages = new ArraySet<>();
+ private static final Object sLock = new Object();
+
+ @GuardedBy("sLock")
+ private static final SparseIntArray sSystemUids = new SparseIntArray();
+
+ @GuardedBy("sLock")
+ private static Signature sSystemSignature;
private final Object mWriteLock = new Object();
@@ -634,7 +641,7 @@ final class SettingsState {
/**
* Dump historical operations as a proto buf.
*
- * @param proto The proto buf stream to dump to
+ * @param proto The proto buf stream to dump to
* @param fieldId The repeated field ID to use to save an operation to.
*/
void dumpHistoricalOperations(@NonNull ProtoOutputStream proto, long fieldId) {
@@ -1041,7 +1048,6 @@ final class SettingsState {
/**
* Uses AtomicFile to check if the file or its backup exists.
- *
* @param file The file to check for existence
* @return whether the original or backup exist
*/
@@ -1301,9 +1307,9 @@ final class SettingsState {
if (NULL_VALUE.equals(value)) {
value = null;
}
+
final boolean callerSystem = !forceNonSystemPackage &&
- !isNull() && (isCalledFromSystem(packageName)
- || isSystemPackage(mContext, packageName));
+ !isNull() && isSystemPackage(mContext, packageName);
// Settings set by the system are always defaults.
if (callerSystem) {
setDefault = true;
@@ -1428,92 +1434,98 @@ final class SettingsState {
return sb.toString();
}
- // Cache the list of names of system packages. This is only called once on system boot.
- public static void cacheSystemPackageNamesAndSystemSignature(@NonNull Context context) {
- final PackageManager packageManager = context.getPackageManager();
- final long identity = Binder.clearCallingIdentity();
- try {
- sSystemPackages.add(SYSTEM_PACKAGE_NAME);
- // Cache SetupWizard package name.
- final String setupWizPackageName = packageManager.getSetupWizardPackageName();
- if (setupWizPackageName != null) {
- sSystemPackages.add(setupWizPackageName);
+ // Check if a specific package belonging to the caller is part of the system package.
+ public static boolean isSystemPackage(Context context, String packageName) {
+ final int callingUid = Binder.getCallingUid();
+ final int callingUserId = UserHandle.getUserId(callingUid);
+ return isSystemPackage(context, packageName, callingUid, callingUserId);
+ }
+
+ // Check if a specific package, uid, and user ID are part of the system package.
+ public static boolean isSystemPackage(Context context, String packageName, int uid,
+ int userId) {
+ synchronized (sLock) {
+ if (SYSTEM_PACKAGE_NAME.equals(packageName)) {
+ return true;
}
- final List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0);
- final int installedPackagesCount = packageInfos.size();
- for (int i = 0; i < installedPackagesCount; i++) {
- if (shouldAddToSystemPackages(packageInfos.get(i))) {
- sSystemPackages.add(packageInfos.get(i).packageName);
+
+ // Shell and Root are not considered a part of the system
+ if (SHELL_PACKAGE_NAME.equals(packageName)
+ || ROOT_PACKAGE_NAME.equals(packageName)) {
+ return false;
+ }
+
+ if (uid != INVALID_UID) {
+ // Native services running as a special UID get a pass
+ final int callingAppId = UserHandle.getAppId(uid);
+ if (callingAppId < FIRST_APPLICATION_UID) {
+ sSystemUids.put(callingAppId, callingAppId);
+ return true;
}
}
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- private static boolean shouldAddToSystemPackages(@NonNull PackageInfo packageInfo) {
- // Shell and Root are not considered a part of the system
- if (isShellOrRoot(packageInfo.packageName)) {
- return false;
- }
- // Already added
- if (sSystemPackages.contains(packageInfo.packageName)) {
- return false;
- }
- return isSystemPackage(packageInfo.applicationInfo);
- }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ try {
+ uid = context.getPackageManager().getPackageUidAsUser(packageName, 0, userId);
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
- private static boolean isShellOrRoot(@NonNull String packageName) {
- return (SHELL_PACKAGE_NAME.equals(packageName)
- || ROOT_PACKAGE_NAME.equals(packageName));
- }
+ // If the system or a special system UID (like telephony), done.
+ if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
+ sSystemUids.put(uid, uid);
+ return true;
+ }
- private static boolean isCalledFromSystem(@NonNull String packageName) {
- // Shell and Root are not considered a part of the system
- if (isShellOrRoot(packageName)) {
- return false;
- }
- final int callingUid = Binder.getCallingUid();
- // Native services running as a special UID get a pass
- final int callingAppId = UserHandle.getAppId(callingUid);
- return (callingAppId < FIRST_APPLICATION_UID);
- }
+ // If already known system component, done.
+ if (sSystemUids.indexOfKey(uid) >= 0) {
+ return true;
+ }
- public static boolean isSystemPackage(@NonNull Context context, @NonNull String packageName) {
- // Check shell or root before trying to retrieve ApplicationInfo to fail fast
- if (isShellOrRoot(packageName)) {
- return false;
- }
- // If it's a known system package or known to be platform signed
- if (sSystemPackages.contains(packageName)) {
- return true;
- }
- ApplicationInfo aInfo = null;
- try {
- // Notice that this makes a call to package manager inside the lock
- aInfo = context.getPackageManager().getApplicationInfo(packageName, 0);
- } catch (PackageManager.NameNotFoundException ignored) {
- }
- return isSystemPackage(aInfo);
- }
+ // If SetupWizard, done.
+ String setupWizPackage = context.getPackageManager().getSetupWizardPackageName();
+ if (packageName.equals(setupWizPackage)) {
+ sSystemUids.put(uid, uid);
+ return true;
+ }
+
+ // If a persistent system app, done.
+ PackageInfo packageInfo;
+ try {
+ packageInfo = context.getPackageManager().getPackageInfoAsUser(
+ packageName, PackageManager.GET_SIGNATURES, userId);
+ if ((packageInfo.applicationInfo.flags
+ & ApplicationInfo.FLAG_PERSISTENT) != 0
+ && (packageInfo.applicationInfo.flags
+ & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ sSystemUids.put(uid, uid);
+ return true;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+
+ // Last check if system signed.
+ if (sSystemSignature == null) {
+ try {
+ sSystemSignature = context.getPackageManager().getPackageInfoAsUser(
+ SYSTEM_PACKAGE_NAME, PackageManager.GET_SIGNATURES,
+ UserHandle.USER_SYSTEM).signatures[0];
+ } catch (PackageManager.NameNotFoundException e) {
+ /* impossible */
+ return false;
+ }
+ }
+ if (sSystemSignature.equals(packageInfo.signatures[0])) {
+ sSystemUids.put(uid, uid);
+ return true;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
- private static boolean isSystemPackage(@Nullable ApplicationInfo aInfo) {
- if (aInfo == null) {
return false;
}
- // If the system or a special system UID (like telephony), done.
- if (aInfo.uid < FIRST_APPLICATION_UID) {
- return true;
- }
- // If a persistent system app, done.
- if ((aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
- && (aInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
- return true;
- }
- // Platform signed packages are considered to be from the system
- if (aInfo.isSignedWithPlatformKey()) {
- return true;
- }
- return false;
}
}
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 3877b1e00048..150d10db2692 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -593,6 +593,7 @@ public class SettingsBackupTest {
Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER,
Settings.Global.CACHED_APPS_FREEZER_ENABLED,
Settings.Global.APP_INTEGRITY_VERIFICATION_TIMEOUT,
+ Settings.Global.KEY_CHORD_POWER_VOLUME_UP,
Settings.Global.ADVANCED_BATTERY_USAGE_AMOUNT);
private static final Set<String> BACKUP_DENY_LIST_SECURE_SETTINGS =
@@ -750,7 +751,7 @@ public class SettingsBackupTest {
Settings.Secure.SUPPRESS_DOZE,
Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED,
Settings.Secure.ACCESSIBILITY_SHOW_WINDOW_MAGNIFICATION_PROMPT,
- Settings.Secure.TRANSFORM_ENABLED);
+ Settings.Secure.UI_TRANSLATION_ENABLED);
@Test
public void systemSettingsBackedUpOrDenied() {
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 657435326d15..8b226c926c99 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -71,6 +71,7 @@ android_library {
],
static_libs: [
"WindowManager-Shell",
+ "SystemUIAnimationLib",
"SystemUIPluginLib",
"SystemUISharedLib",
"SystemUI-statsd",
@@ -139,6 +140,7 @@ android_library {
"src/**/I*.aidl",
],
static_libs: [
+ "SystemUIAnimationLib",
"SystemUIPluginLib",
"SystemUISharedLib",
"SystemUI-statsd",
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 380174959189..a83478469637 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -276,6 +276,8 @@
<!-- Permission to make accessibility service access Bubbles -->
<uses-permission android:name="android.permission.ADD_TRUSTED_DISPLAY" />
+ <!-- Permission for Smartspace. -->
+ <uses-permission android:name="android.permission.MANAGE_SMARTSPACE" />
<protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
@@ -680,7 +682,7 @@
<activity
android:name=".settings.brightness.BrightnessDialog"
android:label="@string/quick_settings_brightness_dialog_title"
- android:theme="@*android:style/Theme.DeviceDefault.SystemUI.Dialog"
+ android:theme="@style/Theme.SystemUI.QuickSettings.BrightnessDialog"
android:finishOnCloseSystemDialogs="true"
android:launchMode="singleInstance"
android:excludeFromRecents="true"
diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/Android.bp
new file mode 100644
index 000000000000..ab9ab831157c
--- /dev/null
+++ b/packages/SystemUI/animation/Android.bp
@@ -0,0 +1,44 @@
+// 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_packages_SystemUI_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"],
+}
+
+android_library {
+
+ name: "SystemUIAnimationLib",
+
+ srcs: [
+ "src/**/*.java",
+ "src/**/*.kt",
+ ],
+
+ resource_dirs: [
+ "res",
+ ],
+
+ static_libs: [
+ "PluginCoreLib",
+ "SystemUI-sensors",
+ ],
+
+ manifest: "AndroidManifest.xml",
+
+}
diff --git a/packages/SystemUI/animation/AndroidManifest.xml b/packages/SystemUI/animation/AndroidManifest.xml
new file mode 100644
index 000000000000..321cc53142c6
--- /dev/null
+++ b/packages/SystemUI/animation/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.systemui.animation">
+
+
+</manifest>
diff --git a/packages/SystemUI/animation/res/interpolator/launch_animation_interpolator_x.xml b/packages/SystemUI/animation/res/interpolator/launch_animation_interpolator_x.xml
new file mode 100644
index 000000000000..620dd4891b9b
--- /dev/null
+++ b/packages/SystemUI/animation/res/interpolator/launch_animation_interpolator_x.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0, 0 C 0.1217, 0.0462, 0.15, 0.4686, 0.1667, 0.66 C 0.1834, 0.8878, 0.1667, 1, 1, 1" /> \ No newline at end of file
diff --git a/packages/SystemUI/animation/res/interpolator/launch_animation_interpolator_y.xml b/packages/SystemUI/animation/res/interpolator/launch_animation_interpolator_y.xml
new file mode 100644
index 000000000000..a268abce0c27
--- /dev/null
+++ b/packages/SystemUI/animation/res/interpolator/launch_animation_interpolator_y.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0,0 C 0.05, 0, 0.133333, 0.06, 0.166666, 0.4 C 0.208333, 0.82, 0.25, 1, 1, 1" /> \ No newline at end of file
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index 5af8dab764a1..da78a7c24d0f 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -1,10 +1,11 @@
-package com.android.systemui.plugins.animation
+package com.android.systemui.animation
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.app.ActivityManager
import android.app.PendingIntent
+import android.content.Context
import android.graphics.Matrix
import android.graphics.Rect
import android.os.RemoteException
@@ -16,7 +17,7 @@ import android.view.RemoteAnimationTarget
import android.view.SyncRtSurfaceTransactionApplier
import android.view.View
import android.view.WindowManager
-import android.view.animation.LinearInterpolator
+import android.view.animation.AnimationUtils
import android.view.animation.PathInterpolator
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.policy.ScreenDecorationsUtils
@@ -26,24 +27,18 @@ import kotlin.math.roundToInt
* A class that allows activities to be started in a seamless way from a view that is transforming
* nicely into the starting window.
*/
-class ActivityLaunchAnimator {
+class ActivityLaunchAnimator(context: Context) {
companion object {
- const val ANIMATION_DURATION = 400L
- const val ANIMATION_DURATION_FADE_OUT_CONTENT = 67L
- const val ANIMATION_DURATION_FADE_IN_WINDOW = 200L
+ const val ANIMATION_DURATION = 500L
+ const val ANIMATION_DURATION_FADE_OUT_CONTENT = 183L
+ const val ANIMATION_DURATION_FADE_IN_WINDOW = 216L
+ const val ANIMATION_DELAY_FADE_IN_WINDOW = 166L
private const val ANIMATION_DURATION_NAV_FADE_IN = 266L
private const val ANIMATION_DURATION_NAV_FADE_OUT = 133L
private const val ANIMATION_DELAY_NAV_FADE_IN =
ANIMATION_DURATION - ANIMATION_DURATION_NAV_FADE_IN
private const val LAUNCH_TIMEOUT = 1000L
- // TODO(b/184121838): Use android.R.interpolator.fast_out_extra_slow_in instead.
- // TODO(b/184121838): Move com.android.systemui.Interpolators in an animation library we can
- // reuse here.
- private val ANIMATION_INTERPOLATOR = PathInterpolator(0.4f, 0f, 0.2f, 1f)
- private val LINEAR_INTERPOLATOR = LinearInterpolator()
- private val ALPHA_IN_INTERPOLATOR = PathInterpolator(0.4f, 0f, 1f, 1f)
- private val ALPHA_OUT_INTERPOLATOR = PathInterpolator(0f, 0f, 0.8f, 1f)
private val NAV_FADE_IN_INTERPOLATOR = PathInterpolator(0f, 0f, 0f, 1f)
private val NAV_FADE_OUT_INTERPOLATOR = PathInterpolator(0.2f, 0f, 1f, 1f)
@@ -61,6 +56,14 @@ class ActivityLaunchAnimator {
}
}
+ /** The interpolator used for the width, height, Y position and corner radius. */
+ private val animationInterpolator = AnimationUtils.loadInterpolator(context,
+ R.interpolator.launch_animation_interpolator_y)
+
+ /** The interpolator used for the X position. */
+ private val animationInterpolatorX = AnimationUtils.loadInterpolator(context,
+ R.interpolator.launch_animation_interpolator_x)
+
/**
* Start an intent and animate the opening window. The intent will be started by running
* [intentStarter], which should use the provided [RemoteAnimationAdapter] and return the launch
@@ -112,6 +115,10 @@ class ActivityLaunchAnimator {
startIntentWithAnimation(controller) { intentStarter.startPendingIntent(it) }
}
+ /** Create a new animation [Runner] controlled by [controller]. */
+ @VisibleForTesting
+ fun createRunner(controller: Controller): Runner = Runner(controller)
+
interface PendingIntentStarter {
/**
* Start a pending intent using the provided [animationAdapter] and return the launch
@@ -216,8 +223,13 @@ class ActivityLaunchAnimator {
var backgroundAlpha: Float = 1f
) {
private val startTop = top
+ private val startBottom = bottom
private val startLeft = left
private val startRight = right
+ private val startWidth = width
+ private val startHeight = height
+ val startCenterX = centerX
+ val startCenterY = centerY
val width: Int
get() = right - left
@@ -228,15 +240,30 @@ class ActivityLaunchAnimator {
open val topChange: Int
get() = top - startTop
+ open val bottomChange: Int
+ get() = bottom - startBottom
+
val leftChange: Int
get() = left - startLeft
val rightChange: Int
get() = right - startRight
+
+ val widthRatio: Float
+ get() = width.toFloat() / startWidth
+
+ val heightRatio: Float
+ get() = height.toFloat() / startHeight
+
+ val centerX: Float
+ get() = left + width / 2f
+
+ val centerY: Float
+ get() = top + height / 2f
}
@VisibleForTesting
- class Runner(private val controller: Controller) : IRemoteAnimationRunner.Stub() {
+ inner class Runner(private val controller: Controller) : IRemoteAnimationRunner.Stub() {
private val rootView = controller.getRootView()
@PublishedApi internal val context = rootView.context
private val transactionApplier = SyncRtSurfaceTransactionApplier(rootView)
@@ -316,6 +343,8 @@ class ActivityLaunchAnimator {
val startBottom = state.bottom
val startLeft = state.left
val startRight = state.right
+ val startXCenter = (startLeft + startRight) / 2f
+ val startWidth = startRight - startLeft
val startTopCornerRadius = state.topCornerRadius
val startBottomCornerRadius = state.bottomCornerRadius
@@ -326,6 +355,8 @@ class ActivityLaunchAnimator {
val endBottom = windowBounds.bottom
val endLeft = windowBounds.left
val endRight = windowBounds.right
+ val endXCenter = (endLeft + endRight) / 2f
+ val endWidth = endRight - endLeft
// TODO(b/184121838): Ensure that we are launching on the same screen.
val rootViewLocation = rootView.locationOnScreen
@@ -349,7 +380,7 @@ class ActivityLaunchAnimator {
val animator = ValueAnimator.ofFloat(0f, 1f)
this.animator = animator
animator.duration = ANIMATION_DURATION
- animator.interpolator = LINEAR_INTERPOLATOR
+ animator.interpolator = Interpolators.LINEAR
animator.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator?, isReverse: Boolean) {
@@ -368,12 +399,15 @@ class ActivityLaunchAnimator {
}
val linearProgress = animation.animatedFraction
- val progress = ANIMATION_INTERPOLATOR.getInterpolation(linearProgress)
+ val progress = animationInterpolator.getInterpolation(linearProgress)
+ val xProgress = animationInterpolatorX.getInterpolation(linearProgress)
+ val xCenter = MathUtils.lerp(startXCenter, endXCenter, xProgress)
+ val halfWidth = lerp(startWidth, endWidth, progress) / 2
state.top = lerp(startTop, endTop, progress).roundToInt()
state.bottom = lerp(startBottom, endBottom, progress).roundToInt()
- state.left = lerp(startLeft, endLeft, progress).roundToInt()
- state.right = lerp(startRight, endRight, progress).roundToInt()
+ state.left = (xCenter - halfWidth).roundToInt()
+ state.right = (xCenter + halfWidth).roundToInt()
state.topCornerRadius = MathUtils.lerp(startTopCornerRadius, endRadius, progress)
state.bottomCornerRadius =
@@ -382,12 +416,12 @@ class ActivityLaunchAnimator {
val contentAlphaProgress = getProgress(linearProgress, 0,
ANIMATION_DURATION_FADE_OUT_CONTENT)
state.contentAlpha =
- 1 - ALPHA_OUT_INTERPOLATOR.getInterpolation(contentAlphaProgress)
+ 1 - Interpolators.ALPHA_OUT.getInterpolation(contentAlphaProgress)
val backgroundAlphaProgress = getProgress(linearProgress,
- ANIMATION_DURATION_FADE_OUT_CONTENT, ANIMATION_DURATION_FADE_IN_WINDOW)
+ ANIMATION_DELAY_FADE_IN_WINDOW, ANIMATION_DURATION_FADE_IN_WINDOW)
state.backgroundAlpha =
- 1 - ALPHA_IN_INTERPOLATOR.getInterpolation(backgroundAlphaProgress)
+ 1 - Interpolators.ALPHA_IN.getInterpolation(backgroundAlphaProgress)
applyStateToWindow(window, state)
navigationBar?.let { applyStateToNavigationBar(it, state, linearProgress) }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
index a5494adedd1d..01ec447e5685 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/animation/GhostedViewLaunchAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
@@ -1,7 +1,8 @@
-package com.android.systemui.plugins.animation
+package com.android.systemui.animation
import android.graphics.Canvas
import android.graphics.ColorFilter
+import android.graphics.Matrix
import android.graphics.PixelFormat
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
@@ -13,6 +14,7 @@ import android.view.GhostView
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
+import kotlin.math.min
/**
* A base implementation of [ActivityLaunchAnimator.Controller] which creates a [ghost][GhostView]
@@ -34,7 +36,9 @@ open class GhostedViewLaunchAnimatorController(
private val rootViewOverlay = rootView.overlay
/** The ghost view that is drawn and animated instead of the ghosted view. */
- private var ghostView: View? = null
+ private var ghostView: GhostView? = null
+ private val initialGhostViewMatrixValues = FloatArray(9) { 0f }
+ private val ghostViewMatrix = Matrix()
/**
* The expanding background view that will be added to [rootView] (below [ghostView]) and
@@ -125,6 +129,9 @@ open class GhostedViewLaunchAnimatorController(
ghostView = GhostView.addGhost(ghostedView, rootView).apply {
setLayerType(View.LAYER_TYPE_HARDWARE, null)
}
+
+ val matrix = ghostView?.animationMatrix ?: Matrix.IDENTITY_MATRIX
+ matrix.getValues(initialGhostViewMatrixValues)
}
override fun onLaunchAnimationProgress(
@@ -133,10 +140,17 @@ open class GhostedViewLaunchAnimatorController(
linearProgress: Float
) {
val ghostView = this.ghostView!!
- ghostView.translationX = (state.leftChange + state.rightChange) / 2.toFloat()
- ghostView.translationY = state.topChange.toFloat()
ghostView.alpha = state.contentAlpha
+ val scale = min(state.widthRatio, state.heightRatio)
+ ghostViewMatrix.setValues(initialGhostViewMatrixValues)
+ ghostViewMatrix.postScale(scale, scale, state.startCenterX, state.startCenterY)
+ ghostViewMatrix.postTranslate(
+ (state.leftChange + state.rightChange) / 2f,
+ (state.topChange + state.bottomChange) / 2f
+ )
+ ghostView.animationMatrix = ghostViewMatrix
+
val backgroundView = this.backgroundView!!
backgroundView.top = state.top
backgroundView.bottom = state.bottom
diff --git a/packages/SystemUI/src/com/android/systemui/Interpolators.java b/packages/SystemUI/animation/src/com/android/systemui/animation/Interpolators.java
index c23bcb8dcbb0..58cef31aaf77 100644
--- a/packages/SystemUI/src/com/android/systemui/Interpolators.java
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/Interpolators.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.systemui;
+package com.android.systemui.animation;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
@@ -24,8 +24,6 @@ import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.PathInterpolator;
-import com.android.systemui.statusbar.notification.stack.HeadsUpAppearInterpolator;
-
/**
* Utility class to receive interpolators from
*/
@@ -48,12 +46,11 @@ public class Interpolators {
public static final Interpolator ACCELERATE_DECELERATE = new AccelerateDecelerateInterpolator();
public static final Interpolator DECELERATE_QUINT = new DecelerateInterpolator(2.5f);
public static final Interpolator CUSTOM_40_40 = new PathInterpolator(0.4f, 0f, 0.6f, 1f);
- public static final Interpolator HEADS_UP_APPEAR = new HeadsUpAppearInterpolator();
public static final Interpolator ICON_OVERSHOT = new PathInterpolator(0.4f, 0f, 0.2f, 1.4f);
- public static final Interpolator ICON_OVERSHOT_LESS
- = new PathInterpolator(0.4f, 0f, 0.2f, 1.1f);
- public static final Interpolator PANEL_CLOSE_ACCELERATED
- = new PathInterpolator(0.3f, 0, 0.5f, 1);
+ public static final Interpolator ICON_OVERSHOT_LESS = new PathInterpolator(0.4f, 0f, 0.2f,
+ 1.1f);
+ public static final Interpolator PANEL_CLOSE_ACCELERATED = new PathInterpolator(0.3f, 0, 0.5f,
+ 1);
public static final Interpolator BOUNCE = new BounceInterpolator();
/**
* For state transitions on the control panel that lives in GlobalActions.
diff --git a/packages/SystemUI/plugin/Android.bp b/packages/SystemUI/plugin/Android.bp
index b3aba223c7d7..f415da839738 100644
--- a/packages/SystemUI/plugin/Android.bp
+++ b/packages/SystemUI/plugin/Android.bp
@@ -34,6 +34,7 @@ java_library {
static_libs: [
"PluginCoreLib",
"SystemUI-sensors",
+ "SystemUIAnimationLib",
],
}
diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
index f8a9a0459673..35423a979cbc 100644
--- a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
+++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
@@ -16,7 +16,9 @@
package com.android.systemui.plugins;
+import android.app.smartspace.SmartspaceTarget;
import android.os.Parcelable;
+import android.view.ViewGroup;
import com.android.systemui.plugins.annotations.ProvidesInterface;
@@ -36,9 +38,25 @@ public interface BcSmartspaceDataPlugin extends Plugin {
/** Unregister a listener. */
void unregisterListener(SmartspaceTargetListener listener);
+ /**
+ * Create a view to be shown within the parent. Do not add the view, as the parent
+ * will be responsible for correctly setting the LayoutParams
+ */
+ default SmartspaceView getView(ViewGroup parent) {
+ return null;
+ }
+
+ /** Updates Smartspace data and propagates it to any listeners. */
+ void onTargetsAvailable(List<SmartspaceTarget> targets);
+
/** Provides Smartspace data to registered listeners. */
interface SmartspaceTargetListener {
/** Each Parcelable is a SmartspaceTarget that represents a card. */
void onSmartspaceTargetsUpdated(List<? extends Parcelable> targets);
}
+
+ /** View to which this plugin can be registered, in order to get updates. */
+ interface SmartspaceView {
+ void registerDataProvider(BcSmartspaceDataPlugin plugin);
+ }
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
index 055fe373156a..00bea8da2efc 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
@@ -19,7 +19,7 @@ import android.app.PendingIntent;
import android.content.Intent;
import android.view.View;
-import com.android.systemui.plugins.animation.ActivityLaunchAnimator;
+import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.plugins.annotations.ProvidesInterface;
/**
diff --git a/packages/SystemUI/res-keyguard/font/clock.xml b/packages/SystemUI/res-keyguard/font/clock.xml
index 008b32223ec6..d0867e9aa546 100644
--- a/packages/SystemUI/res-keyguard/font/clock.xml
+++ b/packages/SystemUI/res-keyguard/font/clock.xml
@@ -23,6 +23,5 @@
** Recommended: font with variable width to support AOD => LS animations
-->
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- TODO (b/171376810): switch this font with a variable width clock font for AOSP -->
- <font android:typeface="monospace" android:font="@*android:string/config_headlineFontFamily" />
+ <font android:typeface="monospace"/>
</font-family> \ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
index 6ecbe06fd28b..00c27bf5f10d 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
@@ -25,65 +25,30 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top">
<FrameLayout
- android:id="@+id/clock_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_alignParentTop="true">
- <TextClock
- android:id="@+id/default_clock_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:gravity="center_horizontal"
- android:paddingBottom="@dimen/title_clock_padding"
- android:letterSpacing="0.02"
- android:textColor="?attr/wallpaperTextColor"
- android:singleLine="true"
- style="@style/widget_big"
- android:format12Hour="@string/keyguard_widget_12_hours_format"
- android:format24Hour="@string/keyguard_widget_24_hours_format"
- android:elegantTextHeight="false"
- />
- <TextClock
- android:id="@+id/default_clock_view_bold"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom|center_horizontal"
- android:gravity="center_horizontal"
- android:textColor="?attr/wallpaperTextColor"
- android:singleLine="true"
- style="@style/widget_title_bold"
- android:format12Hour="@string/keyguard_widget_12_hours_format"
- android:format24Hour="@string/keyguard_widget_24_hours_format"
- android:elegantTextHeight="false"
- android:visibility="invisible"
- />
- </FrameLayout>
- <FrameLayout
- android:id="@+id/new_lockscreen_clock_view"
+ android:id="@+id/lockscreen_clock_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
- android:visibility="gone">
+ android:paddingStart="@dimen/clock_padding_start">
<com.android.keyguard.AnimatableClockView
android:id="@+id/animatable_clock_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
- android:textSize="86dp"
+ android:textSize="@dimen/clock_text_size"
android:fontFamily="@font/clock"
android:typeface="monospace"
android:elegantTextHeight="false"
android:singleLine="true"
+ chargeAnimationDelay="350"
dozeWeight="200"
lockScreenWeight="400"
/>
</FrameLayout>
<FrameLayout
- android:id="@+id/new_lockscreen_clock_view_large"
+ android:id="@+id/lockscreen_clock_view_large"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/keyguard_status_area"
@@ -98,6 +63,7 @@
android:fontFamily="@font/clock"
android:typeface="monospace"
android:elegantTextHeight="false"
+ chargeAnimationDelay="200"
dozeWeight="200"
lockScreenWeight="400"
/>
@@ -106,7 +72,8 @@
android:id="@+id/keyguard_status_area"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_below="@id/clock_view" />
+ android:layout_alignParentStart="true"
+ android:layout_below="@id/lockscreen_clock_view" />
<com.android.systemui.statusbar.phone.NotificationIconContainer
android:id="@+id/left_aligned_notification_icon_container"
@@ -114,6 +81,6 @@
android:layout_height="@dimen/notification_shelf_height"
android:layout_marginTop="@dimen/widget_vertical_padding"
android:layout_below="@id/keyguard_status_area"
- android:visibility="gone"
+ android:paddingStart="@dimen/below_clock_padding_start"
/>
</com.android.keyguard.KeyguardClockSwitch>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
index 9f3ca7459a6b..95eb5c1d5f1a 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
@@ -25,6 +25,7 @@
android:layout_gravity="center_horizontal"
android:clipToPadding="false"
android:orientation="vertical"
+ android:paddingStart="@dimen/below_clock_padding_start"
android:layout_centerHorizontal="true">
<TextView
android:id="@+id/title"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index 10cd3cba713d..c5ba3d2a36cf 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -70,12 +70,5 @@
android:letterSpacing="0.05"
android:ellipsize="marquee"
android:singleLine="true" />
- <com.android.systemui.statusbar.phone.NotificationIconContainer
- android:id="@+id/clock_notification_icon_container"
- android:layout_width="match_parent"
- android:layout_height="@dimen/notification_shelf_height"
- android:layout_marginTop="@dimen/widget_vertical_padding"
- android:visibility="invisible"
- />
</LinearLayout>
</com.android.keyguard.KeyguardStatusView>
diff --git a/packages/SystemUI/res-keyguard/values/attrs.xml b/packages/SystemUI/res-keyguard/values/attrs.xml
index eb7a1f73fbc9..25be37adac5b 100644
--- a/packages/SystemUI/res-keyguard/values/attrs.xml
+++ b/packages/SystemUI/res-keyguard/values/attrs.xml
@@ -45,5 +45,6 @@
<declare-styleable name="AnimatableClockView">
<attr name="dozeWeight" format="integer" />
<attr name="lockScreenWeight" format="integer" />
+ <attr name="chargeAnimationDelay" format="integer" />
</declare-styleable>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 07bd2e6f0505..9b8035d100ad 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -90,4 +90,8 @@
<dimen name="num_pad_key_width">72dp</dimen>
<dimen name="num_pad_row_margin_bottom">6dp</dimen>
<dimen name="num_pad_key_margin_end">12dp</dimen>
+
+ <!-- additional offset for clock switch area items -->
+ <dimen name="clock_padding_start">28dp</dimen>
+ <dimen name="below_clock_padding_start">32dp</dimen>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 2ffc9927480e..0fef9f15c373 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -17,7 +17,7 @@
*/
-->
-<resources>
+<resources xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<!-- Keyguard PIN pad styles -->
<style name="Keyguard.TextView" parent="@android:style/Widget.DeviceDefault.TextView">
<item name="android:textSize">@dimen/kg_status_line_font_size</item>
@@ -32,7 +32,7 @@
<item name="android:stateListAnimator">@null</item>
</style>
<style name="NumPadKey" parent="Theme.SystemUI">
- <item name="android:colorControlNormal">?android:attr/colorBackground</item>
+ <item name="android:colorControlNormal">?androidprv:attr/colorSurface</item>
<item name="android:colorControlHighlight">?android:attr/colorAccent</item>
<item name="android:background">@drawable/num_pad_key_background</item>
</style>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_01_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_01_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_01_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_02_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_02_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_02_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_03_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_03_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_03_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_04_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_04_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_04_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_05_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_05_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_05_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_06_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_06_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_06_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_07_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_07_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_07_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_08_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_08_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_08_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_09_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_09_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_09_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_10_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_10_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_10_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_11_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_11_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_11_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_12_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_12_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_12_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_13_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_13_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_13_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_14_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_14_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_14_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_15_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_15_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_15_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_16_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_16_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_16_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_17_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_17_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_17_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging__dot_18_pivot_animation.xml b/packages/SystemUI/res/anim/wireless_charging__dot_18_pivot_animation.xml
deleted file mode 100644
index fd5561b68dc6..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging__dot_18_pivot_animation.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0.0,-25.0 c 0.0,-11.16667 0.0,-55.83333 0.0,-67.0"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_10_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_10_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_10_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_11_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_11_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_11_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_12_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_12_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_12_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_13_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_13_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_13_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_14_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_14_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_14_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_15_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_15_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_15_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_16_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_16_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_16_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_17_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_17_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_17_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_18_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_18_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_18_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_1_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_1_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_1_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_2_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_2_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_2_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_3_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_3_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_3_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_4_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_4_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_4_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_5_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_5_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_5_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_6_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_6_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_6_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_7_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_7_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_7_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_8_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_8_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_8_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_9_animation.xml b/packages/SystemUI/res/anim/wireless_charging_ellipse_path_9_animation.xml
deleted file mode 100644
index d20e741e6a2f..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_ellipse_path_9_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="150"
- android:propertyName="pathData"
- android:valueFrom="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
- android:valueTo="M 0.0,-3.5 c 1.9329966243,0.0 3.5,1.5670033757 3.5,3.5 c 0.0,1.9329966243 -1.5670033757,3.5 -3.5,3.5 c -1.9329966243,0.0 -3.5,-1.5670033757 -3.5,-3.5 c 0.0,-1.9329966243 1.5670033757,-3.5 3.5,-3.5 Z"
- android:valueType="pathType"
- android:interpolator="@interpolator/wireless_charging_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/wireless_charging_null_1_animation.xml b/packages/SystemUI/res/anim/wireless_charging_null_1_animation.xml
deleted file mode 100644
index fffae8029953..000000000000
--- a/packages/SystemUI/res/anim/wireless_charging_null_1_animation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="1166"
- android:propertyName="rotation"
- android:valueFrom="0.0"
- android:valueTo="20.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/drawable/bg_smartspace_media_item.xml b/packages/SystemUI/res/drawable/bg_smartspace_media_item.xml
new file mode 100644
index 000000000000..69390848245d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/bg_smartspace_media_item.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
+ <solid android:color="@android:color/white" />
+ <corners android:radius="@dimen/qs_media_album_radius" />
+</shape> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/brightness_mirror_background.xml b/packages/SystemUI/res/drawable/brightness_mirror_background.xml
index 4b225b763f3e..ae3d31290a3f 100644
--- a/packages/SystemUI/res/drawable/brightness_mirror_background.xml
+++ b/packages/SystemUI/res/drawable/brightness_mirror_background.xml
@@ -15,6 +15,6 @@
~ limitations under the License
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="?android:attr/colorBackgroundFloating" />
+ <solid android:color="?attr/underSurfaceColor" />
<corners android:radius="8dp" />
</shape>
diff --git a/packages/SystemUI/res/drawable/brightness_progress_drawable.xml b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
index 73b02f4fa481..88d8f78fa610 100644
--- a/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
+++ b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
@@ -24,7 +24,7 @@
<shape>
<size android:height="@dimen/rounded_slider_track_width" />
<corners android:radius="@dimen/rounded_slider_track_corner_radius" />
- <solid android:color="?android:attr/textColorPrimary" />
+ <solid android:color="?attr/offStateColor" />
</shape>
</inset>
</item>
diff --git a/packages/SystemUI/res/drawable/brightness_progress_full_drawable.xml b/packages/SystemUI/res/drawable/brightness_progress_full_drawable.xml
index f8f455d390c7..ceef9f909c97 100644
--- a/packages/SystemUI/res/drawable/brightness_progress_full_drawable.xml
+++ b/packages/SystemUI/res/drawable/brightness_progress_full_drawable.xml
@@ -16,12 +16,13 @@
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:priv-android="http://schemas.android.com/apk/prv/res/android"
android:autoMirrored="true">
<item android:id="@+id/slider_foreground"
android:height="@dimen/rounded_slider_height">
<shape>
<size android:height="@dimen/rounded_slider_height" />
- <solid android:color="?android:attr/colorControlActivated" />
+ <solid android:color="?priv-android:attr/colorAccentPrimary" />
<corners android:radius="@dimen/rounded_slider_corner_radius"/>
</shape>
</item>
diff --git a/packages/SystemUI/res/drawable/circle_wallet_primary_50dp.xml b/packages/SystemUI/res/drawable/circle_wallet_primary_56dp.xml
index 41d88b4c4ca8..3d4c23315e4b 100644
--- a/packages/SystemUI/res/drawable/circle_wallet_primary_50dp.xml
+++ b/packages/SystemUI/res/drawable/circle_wallet_primary_56dp.xml
@@ -16,8 +16,8 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size
- android:height="50dp"
- android:width="50dp" />
+ android:height="56dp"
+ android:width="56dp" />
<solid android:color="@android:color/transparent" />
<stroke android:width="2dp" android:color="#AECBFA" />
</shape>
diff --git a/packages/SystemUI/res/drawable/circle_wallet_secondary_56dp.xml b/packages/SystemUI/res/drawable/circle_wallet_secondary_56dp.xml
new file mode 100644
index 000000000000..1634e2db3322
--- /dev/null
+++ b/packages/SystemUI/res/drawable/circle_wallet_secondary_56dp.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <size
+ android:height="56dp"
+ android:width="56dp" />
+ <solid android:color="@android:color/transparent" />
+ <stroke android:width="2dp" android:color="@color/GM2_grey_300" />
+</shape>
diff --git a/packages/SystemUI/res/drawable/ic_wallet_lockscreen.xml b/packages/SystemUI/res/drawable/ic_wallet_lockscreen.xml
new file mode 100644
index 000000000000..2f8f11d72331
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_wallet_lockscreen.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright 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.
+*/
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <group>
+ <clip-path
+ android:pathData="M2.15,1.54h20v21h-20z"/>
+ <path
+ android:pathData="M19,21.83H5.35a3.19,3.19 0,0 1,-3.2 -3.19v-7A3.19,3.19 0,0 1,5.35 8.5H19a3.19,3.19 0,0 1,3.19 3.19v7A3.19,3.19 0,0 1,19 21.83ZM5.35,10.44A1.25,1.25 0,0 0,4.1 11.69v7a1.25,1.25 0,0 0,1.25 1.24H19a1.25,1.25 0,0 0,1.25 -1.24v-7A1.25,1.25 0,0 0,19 10.44Z"
+ android:fillColor="#FF000000" />
+ <path
+ android:pathData="M4.7,10.16 L4.21,8.57 16,5a3.56,3.56 0,0 1,3.1 0.25c1,0.67 1.65,2 1.89,4l-1.66,0.2C19.12,8 18.72,7 18.15,6.62a2,2 0,0 0,-1.7 0Z"
+ android:fillColor="#FF000000" />
+ <path
+ android:pathData="M4.43,10.47l-1,-1.34 7.31,-5.44c3,-1.86 5.51,1 6.33,2L15.82,6.77c-2.1,-2.44 -3.23,-2.26 -4.14,-1.7Z"
+ android:fillColor="#FF000000" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/notification_guts_bg.xml b/packages/SystemUI/res/drawable/notification_guts_bg.xml
index d62687883c35..bd9394bf9f8a 100644
--- a/packages/SystemUI/res/drawable/notification_guts_bg.xml
+++ b/packages/SystemUI/res/drawable/notification_guts_bg.xml
@@ -15,8 +15,9 @@
~ limitations under the License
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="?android:attr/colorBackground" />
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+ <solid android:color="?androidprv:attr/colorSurface" />
<!--The radius is 1dp smaller than the notification one, to avoid aliasing bugs on the corners -->
<corners android:radius="1dp" />
</shape>
diff --git a/packages/SystemUI/res/drawable/notification_material_bg.xml b/packages/SystemUI/res/drawable/notification_material_bg.xml
index 1e9be2fb9b05..085263a031cf 100644
--- a/packages/SystemUI/res/drawable/notification_material_bg.xml
+++ b/packages/SystemUI/res/drawable/notification_material_bg.xml
@@ -16,10 +16,11 @@
-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:color="@color/notification_ripple_untinted_color">
<item>
<shape>
- <solid android:color="?android:attr/colorBackground" />
+ <solid android:color="?androidprv:attr/colorSurface" />
</shape>
</item>
</ripple> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_background_primary.xml b/packages/SystemUI/res/drawable/qs_background_primary.xml
index 0a3afc575c4a..30d026ec2948 100644
--- a/packages/SystemUI/res/drawable/qs_background_primary.xml
+++ b/packages/SystemUI/res/drawable/qs_background_primary.xml
@@ -16,7 +16,7 @@
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android">
<shape>
- <solid android:color="?android:attr/colorBackground"/>
+ <solid android:color="?attr/underSurfaceColor"/>
<corners android:radius="@dimen/notification_corner_radius" />
</shape>
</inset> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_customize_tile_decoration.xml b/packages/SystemUI/res/drawable/qs_customize_tile_decoration.xml
index f086cec01234..1124a9220a2c 100644
--- a/packages/SystemUI/res/drawable/qs_customize_tile_decoration.xml
+++ b/packages/SystemUI/res/drawable/qs_customize_tile_decoration.xml
@@ -14,4 +14,4 @@
limitations under the License.
-->
<color xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="@color/qs_customize_decoration"/> \ No newline at end of file
+ android:color="?android:attr/colorBackground"/> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_customizer_background_primary.xml b/packages/SystemUI/res/drawable/qs_customizer_background_primary.xml
index c2d0841a1b8f..ea0aafd321e1 100644
--- a/packages/SystemUI/res/drawable/qs_customizer_background_primary.xml
+++ b/packages/SystemUI/res/drawable/qs_customizer_background_primary.xml
@@ -15,7 +15,7 @@
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android">
<shape>
- <solid android:color="?android:attr/colorBackgroundFloating"/>
+ <solid android:color="?attr/underSurfaceColor"/>
<corners android:radius="?android:attr/dialogCornerRadius" />
</shape>
</inset>
diff --git a/packages/SystemUI/res/drawable/qs_customizer_toolbar.xml b/packages/SystemUI/res/drawable/qs_customizer_toolbar.xml
index 416583013e64..ef950fe67ad2 100644
--- a/packages/SystemUI/res/drawable/qs_customizer_toolbar.xml
+++ b/packages/SystemUI/res/drawable/qs_customizer_toolbar.xml
@@ -15,6 +15,6 @@
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android">
<shape>
- <solid android:color="?android:attr/colorBackgroundFloating"/>
+ <solid android:color="?attr/underSurfaceColor"/>
</shape>
</inset>
diff --git a/packages/SystemUI/res/drawable/privacy_dialog_bg.xml b/packages/SystemUI/res/drawable/qs_dialog_bg.xml
index 96136c4afab8..b307781c6ac4 100644
--- a/packages/SystemUI/res/drawable/privacy_dialog_bg.xml
+++ b/packages/SystemUI/res/drawable/qs_dialog_bg.xml
@@ -18,5 +18,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="?android:attr/colorBackground" />
- <corners android:radius="@dimen/ongoing_appops_dialog_bg_corner_radius" />
+ <corners android:radius="?android:attr/dialogCornerRadius" />
</shape> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/wallet_button.xml b/packages/SystemUI/res/drawable/wallet_action_button_bg.xml
index bf7625fa956f..bf7625fa956f 100644
--- a/packages/SystemUI/res/drawable/wallet_button.xml
+++ b/packages/SystemUI/res/drawable/wallet_action_button_bg.xml
diff --git a/packages/SystemUI/res/drawable/wallet_app_button_bg.xml b/packages/SystemUI/res/drawable/wallet_app_button_bg.xml
new file mode 100644
index 000000000000..1136b9d208af
--- /dev/null
+++ b/packages/SystemUI/res/drawable/wallet_app_button_bg.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape android:shape="rectangle">
+ <stroke android:width="1dp" android:color="@color/GM2_grey_300"/>
+ <solid android:color="@android:color/transparent"/>
+ <corners android:radius="24dp"/>
+ </shape>
+ </item>
+</selector>
diff --git a/packages/SystemUI/res/drawable/wallet_lockscreen_bg.xml b/packages/SystemUI/res/drawable/wallet_lockscreen_bg.xml
new file mode 100644
index 000000000000..1535e7276a6f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/wallet_lockscreen_bg.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright 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.
+*/
+-->
+<ripple
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:color="?android:attr/textColorPrimary">
+ <item>
+ <shape
+ android:shape="oval">
+ <solid android:color="?androidprv:attr/colorSurface"/>
+ <size
+ android:width="@dimen/keyguard_affordance_width"
+ android:height="@dimen/keyguard_affordance_height"/>
+ </shape>
+ </item>
+</ripple>
+
diff --git a/packages/SystemUI/res/drawable/wireless_charging.xml b/packages/SystemUI/res/drawable/wireless_charging.xml
deleted file mode 100644
index 0bf633a847ba..000000000000
--- a/packages/SystemUI/res/drawable/wireless_charging.xml
+++ /dev/null
@@ -1,300 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<vector
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:name="wireless_charging"
- android:width="200dp"
- android:viewportWidth="200"
- android:height="200dp"
- android:viewportHeight="200" >
- <group
- android:name="null_1"
- android:translateX="100"
- android:translateY="100" >
- <group
- android:name="dot_01" >
- <group
- android:name="dot_01_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_1" >
- <path
- android:name="ellipse_path_1"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_02"
- android:rotation="20" >
- <group
- android:name="dot_02_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_2" >
- <path
- android:name="ellipse_path_2"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_03"
- android:rotation="40" >
- <group
- android:name="dot_03_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_3" >
- <path
- android:name="ellipse_path_3"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_04"
- android:rotation="60" >
- <group
- android:name="dot_04_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_4" >
- <path
- android:name="ellipse_path_4"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_05"
- android:rotation="80" >
- <group
- android:name="dot_05_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_5" >
- <path
- android:name="ellipse_path_5"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_06"
- android:rotation="100" >
- <group
- android:name="dot_06_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_6" >
- <path
- android:name="ellipse_path_6"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_07"
- android:rotation="120" >
- <group
- android:name="dot_07_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_7" >
- <path
- android:name="ellipse_path_7"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_08"
- android:rotation="140" >
- <group
- android:name="dot_08_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_8" >
- <path
- android:name="ellipse_path_8"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_09"
- android:rotation="160" >
- <group
- android:name="dot_09_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_9" >
- <path
- android:name="ellipse_path_9"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_10"
- android:rotation="180" >
- <group
- android:name="dot_10_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_10" >
- <path
- android:name="ellipse_path_10"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_11"
- android:rotation="200" >
- <group
- android:name="dot_11_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_11" >
- <path
- android:name="ellipse_path_11"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_12"
- android:rotation="220" >
- <group
- android:name="dot_12_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_12" >
- <path
- android:name="ellipse_path_12"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_13"
- android:rotation="240" >
- <group
- android:name="dot_13_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_13" >
- <path
- android:name="ellipse_path_13"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_14"
- android:rotation="260" >
- <group
- android:name="dot_14_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_14" >
- <path
- android:name="ellipse_path_14"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_15"
- android:rotation="280" >
- <group
- android:name="dot_15_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_15" >
- <path
- android:name="ellipse_path_15"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_16"
- android:rotation="300" >
- <group
- android:name="dot_16_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_16" >
- <path
- android:name="ellipse_path_16"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_17"
- android:rotation="320" >
- <group
- android:name="dot_17_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_17" >
- <path
- android:name="ellipse_path_17"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- <group
- android:name="dot_18"
- android:rotation="340" >
- <group
- android:name="dot_18_pivot"
- android:translateY="-25" >
- <group
- android:name="ellipse_18" >
- <path
- android:name="ellipse_path_18"
- android:fillColor="?attr/chargingAnimColor"
- android:pathData="M 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
- </group>
- </group>
- </group>
- </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/wireless_charging_animation.xml b/packages/SystemUI/res/drawable/wireless_charging_animation.xml
deleted file mode 100644
index 4cf13b198dd1..000000000000
--- a/packages/SystemUI/res/drawable/wireless_charging_animation.xml
+++ /dev/null
@@ -1,133 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<animated-vector
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:drawable="@drawable/wireless_charging" >
- <target
- android:name="null_1"
- android:animation="@anim/wireless_charging_null_1_animation" />
- <target
- android:name="dot_01_pivot"
- android:animation="@anim/wireless_charging__dot_01_pivot_animation" />
- <target
- android:name="ellipse_path_1"
- android:animation="@anim/wireless_charging_ellipse_path_1_animation" />
- <target
- android:name="dot_02_pivot"
- android:animation="@anim/wireless_charging__dot_02_pivot_animation" />
- <target
- android:name="ellipse_path_2"
- android:animation="@anim/wireless_charging_ellipse_path_2_animation" />
- <target
- android:name="dot_03_pivot"
- android:animation="@anim/wireless_charging__dot_03_pivot_animation" />
- <target
- android:name="ellipse_path_3"
- android:animation="@anim/wireless_charging_ellipse_path_3_animation" />
- <target
- android:name="dot_04_pivot"
- android:animation="@anim/wireless_charging__dot_04_pivot_animation" />
- <target
- android:name="ellipse_path_4"
- android:animation="@anim/wireless_charging_ellipse_path_4_animation" />
- <target
- android:name="dot_05_pivot"
- android:animation="@anim/wireless_charging__dot_05_pivot_animation" />
- <target
- android:name="ellipse_path_5"
- android:animation="@anim/wireless_charging_ellipse_path_5_animation" />
- <target
- android:name="dot_06_pivot"
- android:animation="@anim/wireless_charging__dot_06_pivot_animation" />
- <target
- android:name="ellipse_path_6"
- android:animation="@anim/wireless_charging_ellipse_path_6_animation" />
- <target
- android:name="dot_07_pivot"
- android:animation="@anim/wireless_charging__dot_07_pivot_animation" />
- <target
- android:name="ellipse_path_7"
- android:animation="@anim/wireless_charging_ellipse_path_7_animation" />
- <target
- android:name="dot_08_pivot"
- android:animation="@anim/wireless_charging__dot_08_pivot_animation" />
- <target
- android:name="ellipse_path_8"
- android:animation="@anim/wireless_charging_ellipse_path_8_animation" />
- <target
- android:name="dot_09_pivot"
- android:animation="@anim/wireless_charging__dot_09_pivot_animation" />
- <target
- android:name="ellipse_path_9"
- android:animation="@anim/wireless_charging_ellipse_path_9_animation" />
- <target
- android:name="dot_10_pivot"
- android:animation="@anim/wireless_charging__dot_10_pivot_animation" />
- <target
- android:name="ellipse_path_10"
- android:animation="@anim/wireless_charging_ellipse_path_10_animation" />
- <target
- android:name="dot_11_pivot"
- android:animation="@anim/wireless_charging__dot_11_pivot_animation" />
- <target
- android:name="ellipse_path_11"
- android:animation="@anim/wireless_charging_ellipse_path_11_animation" />
- <target
- android:name="dot_12_pivot"
- android:animation="@anim/wireless_charging__dot_12_pivot_animation" />
- <target
- android:name="ellipse_path_12"
- android:animation="@anim/wireless_charging_ellipse_path_12_animation" />
- <target
- android:name="dot_13_pivot"
- android:animation="@anim/wireless_charging__dot_13_pivot_animation" />
- <target
- android:name="ellipse_path_13"
- android:animation="@anim/wireless_charging_ellipse_path_13_animation" />
- <target
- android:name="dot_14_pivot"
- android:animation="@anim/wireless_charging__dot_14_pivot_animation" />
- <target
- android:name="ellipse_path_14"
- android:animation="@anim/wireless_charging_ellipse_path_14_animation" />
- <target
- android:name="dot_15_pivot"
- android:animation="@anim/wireless_charging__dot_15_pivot_animation" />
- <target
- android:name="ellipse_path_15"
- android:animation="@anim/wireless_charging_ellipse_path_15_animation" />
- <target
- android:name="dot_16_pivot"
- android:animation="@anim/wireless_charging__dot_16_pivot_animation" />
- <target
- android:name="ellipse_path_16"
- android:animation="@anim/wireless_charging_ellipse_path_16_animation" />
- <target
- android:name="dot_17_pivot"
- android:animation="@anim/wireless_charging__dot_17_pivot_animation" />
- <target
- android:name="ellipse_path_17"
- android:animation="@anim/wireless_charging_ellipse_path_17_animation" />
- <target
- android:name="dot_18_pivot"
- android:animation="@anim/wireless_charging__dot_18_pivot_animation" />
- <target
- android:name="ellipse_path_18"
- android:animation="@anim/wireless_charging_ellipse_path_18_animation" />
-</animated-vector>
diff --git a/packages/SystemUI/res/layout/brightness_mirror.xml b/packages/SystemUI/res/layout/brightness_mirror.xml
index 8b47ab915fb4..b714767e7d83 100644
--- a/packages/SystemUI/res/layout/brightness_mirror.xml
+++ b/packages/SystemUI/res/layout/brightness_mirror.xml
@@ -16,6 +16,7 @@
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:theme="@style/Theme.SystemUI.QuickSettings"
android:id="@+id/brightness_mirror"
android:layout_width="@dimen/qs_panel_width"
android:layout_height="@dimen/brightness_mirror_height"
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index cf9de5e7e226..69d73c1b94e1 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -90,9 +90,11 @@
android:layout_width="@dimen/keyguard_affordance_width"
android:layout_gravity="bottom|end"
android:scaleType="center"
- android:tint="?attr/wallpaperTextColor"
- android:layout_marginStart="24dp"
- android:layout_marginBottom="48dp"
+ android:tint="?android:attr/textColorPrimary"
+ android:src="@drawable/ic_wallet_lockscreen"
+ android:background="@drawable/wallet_lockscreen_bg"
+ android:layout_marginEnd="@dimen/keyguard_affordance_horizontal_offset"
+ android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
android:visibility="gone" />
<FrameLayout
diff --git a/packages/SystemUI/res/layout/long_screenshot.xml b/packages/SystemUI/res/layout/long_screenshot.xml
index e775de2d8e06..fb783a760c3d 100644
--- a/packages/SystemUI/res/layout/long_screenshot.xml
+++ b/packages/SystemUI/res/layout/long_screenshot.xml
@@ -71,6 +71,7 @@
android:layout_height="0px"
android:paddingTop="8dp"
android:paddingBottom="42dp"
+ android:visibility="gone"
app:layout_constrainedHeight="true"
app:layout_constrainedWidth="true"
app:layout_constraintTop_toTopOf="@id/preview"
diff --git a/packages/SystemUI/res/layout/media_smartspace_recommendations.xml b/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
new file mode 100644
index 000000000000..7e944162fd0d
--- /dev/null
+++ b/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<!-- Layout for media recommendations inside QSPanel carousel -->
+<com.android.systemui.util.animation.TransitionLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/media_recommendations"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:forceHasOverlappingRendering="false"
+ android:background="@drawable/qs_media_background">
+
+ <ImageView
+ android:id="@+id/media_cover1"
+ android:layout_width="@dimen/qs_aa_media_rec_album_size"
+ android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ android:adjustViewBounds="true"
+ android:background="@drawable/bg_smartspace_media_item"
+ android:clipToOutline="true"
+ android:scaleType="centerCrop"/>
+
+ <ImageView
+ android:id="@+id/media_logo1"
+ android:layout_width="@dimen/qs_aa_media_rec_icon_size"
+ android:layout_height="@dimen/qs_aa_media_rec_icon_size" />
+
+ <ImageView
+ android:id="@+id/media_cover2"
+ android:layout_width="@dimen/qs_aa_media_rec_album_size"
+ android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ android:adjustViewBounds="true"
+ android:background="@drawable/bg_smartspace_media_item"
+ android:clipToOutline="true"
+ android:scaleType="centerCrop"/>
+
+ <ImageView
+ android:id="@+id/media_logo2"
+ android:layout_width="@dimen/qs_aa_media_rec_icon_size"
+ android:layout_height="@dimen/qs_aa_media_rec_icon_size" />
+
+ <ImageView
+ android:id="@+id/media_cover3"
+ android:layout_width="@dimen/qs_aa_media_rec_album_size"
+ android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ android:adjustViewBounds="true"
+ android:background="@drawable/bg_smartspace_media_item"
+ android:clipToOutline="true"
+ android:scaleType="centerCrop"/>
+
+ <ImageView
+ android:id="@+id/media_logo3"
+ android:layout_width="@dimen/qs_aa_media_rec_icon_size"
+ android:layout_height="@dimen/qs_aa_media_rec_icon_size" />
+
+ <ImageView
+ android:id="@+id/media_cover4"
+ android:layout_width="@dimen/qs_aa_media_rec_album_size"
+ android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ android:adjustViewBounds="true"
+ android:background="@drawable/bg_smartspace_media_item"
+ android:clipToOutline="true"
+ android:scaleType="centerCrop"/>
+
+ <ImageView
+ android:id="@+id/media_logo4"
+ android:layout_width="@dimen/qs_aa_media_rec_icon_size"
+ android:layout_height="@dimen/qs_aa_media_rec_icon_size" />
+
+</com.android.systemui.util.animation.TransitionLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/people_space_placeholder_layout.xml b/packages/SystemUI/res/layout/people_space_placeholder_layout.xml
index 3ced1ff6c74b..b85d6b097ec7 100644
--- a/packages/SystemUI/res/layout/people_space_placeholder_layout.xml
+++ b/packages/SystemUI/res/layout/people_space_placeholder_layout.xml
@@ -14,6 +14,7 @@
~ limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
diff --git a/packages/SystemUI/res/layout/people_tile_large_empty.xml b/packages/SystemUI/res/layout/people_tile_large_empty.xml
index 1e00307bfc23..69e277015c82 100644
--- a/packages/SystemUI/res/layout/people_tile_large_empty.xml
+++ b/packages/SystemUI/res/layout/people_tile_large_empty.xml
@@ -14,6 +14,7 @@
~ limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:layout_width="match_parent"
android:layout_height="match_parent">
diff --git a/packages/SystemUI/res/layout/people_tile_large_with_content.xml b/packages/SystemUI/res/layout/people_tile_large_with_content.xml
index 9990244ba6c5..af2c5de3b52f 100644
--- a/packages/SystemUI/res/layout/people_tile_large_with_content.xml
+++ b/packages/SystemUI/res/layout/people_tile_large_with_content.xml
@@ -14,6 +14,7 @@
~ limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:id="@+id/item"
android:background="@drawable/people_space_tile_view_card"
android:layout_width="match_parent"
@@ -90,6 +91,7 @@
<ImageView
android:id="@+id/predefined_icon"
+ android:tint="?android:attr/colorAccent"
android:gravity="start|center_vertical"
android:paddingEnd="6dp"
android:layout_width="24dp"
diff --git a/packages/SystemUI/res/layout/people_tile_medium_empty.xml b/packages/SystemUI/res/layout/people_tile_medium_empty.xml
index c35787efec5d..7d9cbb907506 100644
--- a/packages/SystemUI/res/layout/people_tile_medium_empty.xml
+++ b/packages/SystemUI/res/layout/people_tile_medium_empty.xml
@@ -15,6 +15,7 @@
~ limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
diff --git a/packages/SystemUI/res/layout/people_tile_medium_with_content.xml b/packages/SystemUI/res/layout/people_tile_medium_with_content.xml
index db1d46d2117a..c9e4945a7be2 100644
--- a/packages/SystemUI/res/layout/people_tile_medium_with_content.xml
+++ b/packages/SystemUI/res/layout/people_tile_medium_with_content.xml
@@ -16,6 +16,7 @@
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -129,6 +130,7 @@
/>
<ImageView
android:id="@+id/predefined_icon"
+ android:tint="?android:attr/colorAccent"
android:gravity="end|center_vertical"
android:paddingStart="6dp"
android:layout_width="24dp"
diff --git a/packages/SystemUI/res/layout/people_tile_small.xml b/packages/SystemUI/res/layout/people_tile_small.xml
index f0ab187b1a05..34aa8e498231 100644
--- a/packages/SystemUI/res/layout/people_tile_small.xml
+++ b/packages/SystemUI/res/layout/people_tile_small.xml
@@ -14,6 +14,7 @@
~ limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -38,6 +39,7 @@
<ImageView
android:id="@+id/predefined_icon"
+ android:tint="?android:attr/colorAccent"
android:layout_gravity="center"
android:layout_width="18dp"
android:layout_height="22dp"
diff --git a/packages/SystemUI/res/layout/privacy_dialog.xml b/packages/SystemUI/res/layout/privacy_dialog.xml
index 4d77a0d75689..720ae8dbf4d8 100644
--- a/packages/SystemUI/res/layout/privacy_dialog.xml
+++ b/packages/SystemUI/res/layout/privacy_dialog.xml
@@ -28,7 +28,7 @@
android:paddingRight="@dimen/ongoing_appops_dialog_side_padding"
android:paddingBottom="12dp"
android:paddingTop="8dp"
- android:background="@drawable/privacy_dialog_bg"
+ android:background="@drawable/qs_dialog_bg"
/>
<!-- 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 91ffe225fac6..0c8ed9f7ff2a 100644
--- a/packages/SystemUI/res/layout/privacy_dialog_item.xml
+++ b/packages/SystemUI/res/layout/privacy_dialog_item.xml
@@ -51,6 +51,7 @@
/>
<ImageView
+ android:id="@+id/chevron"
android:layout_height="24dp"
android:layout_width="24dp"
android:layout_gravity="center_vertical"
diff --git a/packages/SystemUI/res/layout/wallet_fullscreen.xml b/packages/SystemUI/res/layout/wallet_fullscreen.xml
index dc678481ea6e..b47c2f2e1821 100644
--- a/packages/SystemUI/res/layout/wallet_fullscreen.xml
+++ b/packages/SystemUI/res/layout/wallet_fullscreen.xml
@@ -23,7 +23,7 @@
android:id="@+id/card_carousel_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_marginTop="36dp"
+ android:layout_marginTop="48dp"
android:orientation="vertical">
<ImageView
android:id="@+id/icon"
@@ -31,7 +31,6 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginVertical="10dp"
- android:background="@drawable/circle_wallet_primary_50dp"
android:scaleType="center"
android:contentDescription="@null"/>
<TextView
@@ -50,22 +49,36 @@
android:clipToPadding="false"
android:layout_marginVertical="24dp"/>
+ <Button
+ android:id="@+id/wallet_action_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginVertical="16dp"
+ android:paddingVertical="@dimen/wallet_button_vertical_padding"
+ android:paddingHorizontal="@dimen/wallet_button_horizontal_padding"
+ android:background="@drawable/wallet_action_button_bg"
+ android:textColor="@color/wallet_white"
+ android:textAlignment="center"
+ android:visibility="gone"/>
+
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<Button
- android:id="@+id/wallet_button"
- android:background="@drawable/wallet_button"
- android:textColor="@color/wallet_white"
- android:textAlignment="center"
+ android:id="@+id/wallet_app_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingHorizontal="24dp"
- android:paddingVertical="8dp"
- android:layout_marginVertical="24dp"
- android:layout_gravity="center_horizontal"/>
+ android:layout_gravity="center_horizontal"
+ android:paddingVertical="@dimen/wallet_button_vertical_padding"
+ android:paddingHorizontal="@dimen/wallet_button_horizontal_padding"
+ android:background="@drawable/wallet_app_button_bg"
+ android:text="@string/wallet_app_button_label"
+ android:textColor="@color/GM2_blue_600"
+ android:textAlignment="center"
+ android:layout_marginVertical="24dp"/>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/wireless_charging_layout.xml b/packages/SystemUI/res/layout/wireless_charging_layout.xml
index d82151d30b9e..1312b413f106 100644
--- a/packages/SystemUI/res/layout/wireless_charging_layout.xml
+++ b/packages/SystemUI/res/layout/wireless_charging_layout.xml
@@ -27,14 +27,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
- <!-- Circle animation -->
- <ImageView
- android:id="@+id/wireless_charging_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:src="@drawable/wireless_charging_animation"/>
-
<!-- Text inside circle -->
<LinearLayout
android:id="@+id/wireless_charging_text_layout"
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index 471f36b3849e..e6c5bd0265ed 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -33,7 +33,7 @@
<!-- The color of the text inside a notification -->
<color name="notification_primary_text_color">@*android:color/notification_primary_text_color_dark</color>
- <color name="notif_pill_background">@android:color/system_neutral1_800</color>
+ <color name="notif_pill_background">@*android:color/surface_dark</color>
<color name="notif_pill_text">@android:color/system_neutral1_50</color>
<color name="notification_guts_link_icon_tint">@color/GM2_grey_500</color>
@@ -47,9 +47,6 @@
<color name="notification_section_clear_all_btn_color">@color/GM2_grey_500</color>
<color name="notification_channel_dialog_separator">@color/GM2_grey_700</color>
- <!-- The color of the background in the bottom part of QSCustomizer -->
- <color name="qs_customize_decoration">@color/GM2_grey_900</color>
-
<!-- The color of the background in the separated list of the Global Actions menu -->
<color name="global_actions_separated_background">@color/GM2_grey_900</color>
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index f2df4b9023b1..302e5e417d82 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -40,4 +40,9 @@
<dimen name="qs_tile_margin_top">32dp</dimen>
<dimen name="qs_brightness_padding_top">6dp</dimen>
<dimen name="qs_detail_margin_top">28dp</dimen>
+
+ <!-- In split shade mode notifications should be aligned to QS header so the value should be
+ adjusted to qs header height and height of centered content inside of it:
+ (quick_qs_offset_height (48dp) - ongoing_appops_chip_height (24dp) ) / 2 -->
+ <dimen name="notifications_top_padding_split_shade">12dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 886f98e55d67..e4bdbf3f0727 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -126,6 +126,8 @@
<attr name="wallpaperTextColorSecondary" format="reference|color" />
<attr name="wallpaperTextColorAccent" format="reference|color" />
<attr name="backgroundProtectedStyle" format="reference" />
+ <attr name="offStateColor" format="reference|color" />
+ <attr name="underSurfaceColor" format="reference|color" />
<declare-styleable name="SmartReplyView">
<attr name="spacing" format="dimension" />
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index bc7fcde4ae5d..f699198f93d9 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -35,7 +35,6 @@
<color name="status_bar_clock_color">#FFFFFFFF</color>
<color name="qs_user_detail_icon_muted">#FFFFFFFF</color> <!-- not so muted after all -->
<color name="qs_tile_disabled_color">#9E9E9E</color> <!-- 38% black -->
- <color name="qs_customize_decoration">@color/GM2_grey_300</color>
<color name="qs_footer_action_border">#2E312C</color>
<!-- The color of the background in the separated list of the Global Actions menu -->
@@ -158,7 +157,7 @@
<color name="minimize_dock_shadow_end">#00000000</color>
<color name="default_remote_input_background">@*android:color/notification_default_color</color>
- <color name="notif_pill_background">@android:color/system_neutral2_100</color>
+ <color name="notif_pill_background">@*android:color/surface_light</color>
<color name="notif_pill_text">@android:color/system_neutral1_900</color>
<color name="remote_input_accent">?android:attr/colorAccent</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 3cd7a0b2da58..a19d128a9c67 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -426,6 +426,11 @@
<!-- The padding between the notifications and the quick settings container -->
<dimen name="qs_notification_padding">@dimen/notification_side_paddings</dimen>
+ <!-- In split shade mode notifications should be aligned to QS header so the value should be
+ adjusted to qs header height and height of centered content inside of it:
+ (quick_qs_offset_height (60dp) - ongoing_appops_chip_height (24dp) ) / 2 -->
+ <dimen name="notifications_top_padding_split_shade">18dp</dimen>
+
<!-- Height of the status bar header bar when expanded -->
<dimen name="status_bar_header_height_expanded">124dp</dimen>
@@ -860,9 +865,12 @@
+ 8dp. -->
<dimen name="assist_orb_navbar_scrim_height">56dp</dimen>
- <!-- The width/height of the phone/camera icon view on keyguard. -->
- <dimen name="keyguard_affordance_height">56dp</dimen>
- <dimen name="keyguard_affordance_width">56dp</dimen>
+ <!-- The width/height of the keyguard bottom area icon view on keyguard. -->
+ <dimen name="keyguard_affordance_height">48dp</dimen>
+ <dimen name="keyguard_affordance_width">48dp</dimen>
+ <dimen name="keyguard_affordance_horizontal_offset">32dp</dimen>
+ <dimen name="keyguard_affordance_vertical_offset">32dp</dimen>
+
<!-- The width/height of the unlock icon view on keyguard. -->
<dimen name="keyguard_lock_height">42dp</dimen>
@@ -1086,8 +1094,9 @@
burn-in on AOD. -->
<dimen name="burn_in_prevention_offset_y_large_clock">42dp</dimen>
- <!-- Large clock maximum font size (dp is intentional, to prevent any further scaling) -->
+ <!-- Clock maximum font size (dp is intentional, to prevent any further scaling) -->
<dimen name="large_clock_text_size">150dp</dimen>
+ <dimen name="clock_text_size">86dp</dimen>
<!-- The maximum offset in either direction that icons move to prevent burn-in on AOD. -->
<dimen name="default_burn_in_prevention_offset">15dp</dimen>
@@ -1213,8 +1222,6 @@
<!-- Radius of Ongoing App Ops chip corners -->
<dimen name="ongoing_appops_chip_bg_corner_radius">16dp</dimen>
- <dimen name="ongoing_appops_dialog_bg_corner_radius">@dimen/notification_corner_radius</dimen>
-
<dimen name="ongoing_appops_dialog_side_margins">@dimen/notification_shade_content_margin_horizontal</dimen>
<dimen name="ongoing_appops_dialog_circle_size">32dp</dimen>
@@ -1232,6 +1239,7 @@
<dimen name="qs_media_padding">16dp</dimen>
<dimen name="qs_media_panel_outer_padding">16dp</dimen>
<dimen name="qs_media_album_size">120dp</dimen>
+ <dimen name="qs_media_album_radius">14dp</dimen>
<dimen name="qs_media_icon_size">16dp</dimen>
<dimen name="qs_center_guideline_padding">10dp</dimen>
<dimen name="qs_seamless_icon_size">@dimen/qs_media_icon_size</dimen>
@@ -1244,6 +1252,11 @@
<dimen name="qs_media_enabled_seekbar_vertical_padding">15dp</dimen>
<dimen name="qs_media_disabled_seekbar_vertical_padding">16dp</dimen>
+ <!-- Size of Smartspace media recommendations cards in the QSPanel carousel -->
+ <dimen name="qs_aa_media_rec_album_size">80dp</dimen>
+ <dimen name="qs_aa_media_rec_icon_size">20dp</dimen>
+
+
<!-- Window magnification -->
<dimen name="magnification_border_drag_size">35dp</dimen>
<dimen name="magnification_outer_border_margin">15dp</dimen>
@@ -1442,6 +1455,8 @@
<dimen name="wallet_empty_state_corner_radius">24dp</dimen>
<dimen name="wallet_tile_card_view_height">32dp</dimen>
<dimen name="wallet_tile_card_view_width">50dp</dimen>
+ <dimen name="wallet_button_horizontal_padding">24dp</dimen>
+ <dimen name="wallet_button_vertical_padding">8dp</dimen>
<!-- Ongoing call chip -->
<dimen name="ongoing_call_chip_side_padding">12dp</dimen>
diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml
index 834b482a449e..bbf204844e29 100644
--- a/packages/SystemUI/res/values/flags.xml
+++ b/packages/SystemUI/res/values/flags.xml
@@ -50,4 +50,6 @@
<bool name="flag_charging_ripple">false</bool>
<bool name="flag_ongoing_call_status_bar_chip">true</bool>
+
+ <bool name="flag_smartspace">false</bool>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 269fdc53853b..4ae1c936d1a9 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -245,10 +245,14 @@
<string name="screenshot_dismiss_description">Dismiss screenshot</string>
<!-- Content description indicating that the view is a preview of the screenshot that was just taken [CHAR LIMIT=NONE] -->
<string name="screenshot_preview_description">Screenshot preview</string>
- <!-- Content description for the top boundary of the screenshot being cropped [CHAR LIMIT=NONE] -->
- <string name="screenshot_top_boundary">Top boundary</string>
- <!-- Content description for the bottom boundary of the screenshot being cropped [CHAR LIMIT=NONE] -->
- <string name="screenshot_bottom_boundary">Bottom boundary</string>
+ <!-- Content description for the top boundary of the screenshot being cropped, with the current position as a percentage. [CHAR LIMIT=NONE] -->
+ <string name="screenshot_top_boundary_pct">Top boundary <xliff:g id="percent" example="50">%1$d</xliff:g> percent</string>
+ <!-- Content description for the bottom boundary of the screenshot being cropped, with the current position as a percentage. [CHAR LIMIT=NONE] -->
+ <string name="screenshot_bottom_boundary_pct">Bottom boundary <xliff:g id="percent" example="50">%1$d</xliff:g> percent</string>
+ <!-- Content description for the left boundary of the screenshot being cropped, with the current position as a percentage. [CHAR LIMIT=NONE] -->
+ <string name="screenshot_left_boundary_pct">Left boundary <xliff:g id="percent" example="50">%1$d</xliff:g> percent</string>
+ <!-- Content description for the right boundary of the screenshot being cropped, with the current position as a percentage. [CHAR LIMIT=NONE] -->
+ <string name="screenshot_right_boundary_pct">Right boundary <xliff:g id="percent" example="50">%1$d</xliff:g> percent</string>
<!-- Notification title displayed for screen recording [CHAR LIMIT=50]-->
<string name="screenrecord_name">Screen Recorder</string>
@@ -1646,10 +1650,10 @@
<!-- Wallet strings -->
<!-- Wallet empty state, title [CHAR LIMIT=32] -->
<string name="wallet_title">Wallet</string>
- <!-- Label of the button underneath the card carousel when device is unlocked. [CHAR LIMIT=NONE] -->
- <string name="wallet_button_label_device_unlocked">Show all</string>
- <!-- Label of the button underneath the card carousel when device is locked. [CHAR LIMIT=NONE] -->
- <string name="wallet_button_label_device_locked">Unlock to pay</string>
+ <!-- Label of the button at the bottom prompting user enter wallet app. [CHAR LIMIT=NONE] -->
+ <string name="wallet_app_button_label">Show all</string>
+ <!-- Label of the button underneath the card carousel prompting user unlock device. [CHAR LIMIT=NONE] -->
+ <string name="wallet_action_button_label_unlock">Unlock to pay</string>
<!-- Secondary label of the quick access wallet tile if active. [CHAR LIMIT=32] -->
<string name="wallet_secondary_label_active">Ready</string>
<!-- Secondary label of the quick access wallet tile if no card. [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index ba07829d02fc..ce8c0c2897b8 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -382,6 +382,17 @@
<item name="android:colorError">@*android:color/error_color_material_dark</item>
<item name="android:windowIsFloating">true</item>
<item name="android:homeAsUpIndicator">@drawable/ic_arrow_back</item>
+ <item name="offStateColor">@android:color/system_neutral1_800</item>
+ <item name="underSurfaceColor">@android:color/system_neutral1_1000</item>
+ <item name="android:colorBackground">@android:color/system_neutral1_900</item>
+ </style>
+
+ <style name="Theme.SystemUI.QuickSettings.BrightnessDialog" parent="@android:style/Theme.DeviceDefault.Dialog">
+ <item name="android:dialogCornerRadius">8dp</item>
+ </style>
+
+ <style name="Theme.SystemUI.QuickSettings.Dialog" parent="@android:style/Theme.DeviceDefault.Dialog">
+ <item name="android:dialogCornerRadius">@dimen/notification_corner_radius</item>
</style>
<!-- Overridden by values-television/styles.xml with tv-specific settings -->
@@ -588,10 +599,6 @@
<item name="android:elevation">10dp</item>
</style>
- <style name="Theme.SystemUI.QuickSettings.Edit">
- <item name="android:colorBackground">?android:attr/colorSecondary</item>
- </style>
-
<style name="MediaPlayer.Button" parent="@android:style/Widget.Material.Button.Borderless.Small">
<item name="android:background">@drawable/qs_media_light_source</item>
<item name="android:tint">?android:attr/textColorPrimary</item>
@@ -628,7 +635,12 @@
</style>
<!-- Privacy dialog -->
- <style name="PrivacyDialog" parent="ScreenRecord">
+ <style name="PrivacyDialog" parent="Theme.SystemUI.QuickSettings.Dialog">
+ <item name="android:windowIsTranslucent">true</item>
+ <item name="android:windowBackground">@android:color/transparent</item>
+ <item name="android:windowIsFloating">true</item>
+ <item name="android:backgroundDimEnabled">true</item>
+ <item name="android:windowCloseOnTouchOutside">true</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
</style>
diff --git a/packages/SystemUI/res/xml/media_recommendation.xml b/packages/SystemUI/res/xml/media_recommendation.xml
new file mode 100644
index 000000000000..a1bd231806a1
--- /dev/null
+++ b/packages/SystemUI/res/xml/media_recommendation.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<ConstraintSet
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+
+ <Constraint
+ android:id="@+id/media_cover1"
+ android:layout_width="@dimen/qs_aa_media_rec_album_size"
+ android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/media_cover2"
+ app:layout_constraintHorizontal_weight="1"
+ android:visibility="gone"/>
+
+ <Constraint
+ android:id="@+id/media_logo1"
+ android:layout_width="@dimen/qs_aa_media_rec_icon_size"
+ android:layout_height="@dimen/qs_aa_media_rec_icon_size"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover1"
+ app:layout_constraintBottom_toBottomOf="@+id/media_cover1"
+ android:visibility="gone" />
+
+ <Constraint
+ android:id="@+id/media_cover2"
+ android:layout_width="@dimen/qs_aa_media_rec_album_size"
+ android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toEndOf="@id/media_cover1"
+ app:layout_constraintEnd_toStartOf="@id/media_cover3"
+ app:layout_constraintHorizontal_weight="1"
+ android:visibility="gone"/>
+
+ <Constraint
+ android:id="@+id/media_logo2"
+ android:layout_width="@dimen/qs_aa_media_rec_icon_size"
+ android:layout_height="@dimen/qs_aa_media_rec_icon_size"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover2"
+ app:layout_constraintBottom_toBottomOf="@+id/media_cover2"
+ android:visibility="gone" />
+
+ <Constraint
+ android:id="@+id/media_cover3"
+ android:layout_width="@dimen/qs_aa_media_rec_album_size"
+ android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toEndOf="@id/media_cover2"
+ app:layout_constraintEnd_toStartOf="@id/media_cover4"
+ app:layout_constraintHorizontal_weight="1"
+ android:visibility="gone"/>
+
+ <Constraint
+ android:id="@+id/media_logo3"
+ android:layout_width="@dimen/qs_aa_media_rec_icon_size"
+ android:layout_height="@dimen/qs_aa_media_rec_icon_size"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover3"
+ app:layout_constraintBottom_toBottomOf="@+id/media_cover3"
+ android:visibility="gone" />
+
+ <Constraint
+ android:id="@+id/media_cover4"
+ android:layout_width="@dimen/qs_aa_media_rec_album_size"
+ android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toEndOf="@id/media_cover3"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_weight="1"
+ android:visibility="gone"/>
+
+ <Constraint
+ android:id="@+id/media_logo4"
+ android:layout_width="@dimen/qs_aa_media_rec_icon_size"
+ android:layout_height="@dimen/qs_aa_media_rec_icon_size"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover4"
+ app:layout_constraintBottom_toBottomOf="@+id/media_cover4"
+ android:visibility="gone" />
+
+</ConstraintSet>
diff --git a/packages/SystemUI/res/xml/people_space_widget_info.xml b/packages/SystemUI/res/xml/people_space_widget_info.xml
index b2bf6da65163..e3861470891d 100644
--- a/packages/SystemUI/res/xml/people_space_widget_info.xml
+++ b/packages/SystemUI/res/xml/people_space_widget_info.xml
@@ -15,12 +15,13 @@
-->
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
- android:minWidth="120dp"
- android:minHeight="50dp"
+ android:minWidth="136dp"
+ android:minHeight="55dp"
android:minResizeWidth="60dp"
android:minResizeHeight="50dp"
android:maxResizeHeight="207dp"
android:updatePeriodMillis="60000"
+ android:widgetFeatures="reconfigurable"
android:description="@string/people_tile_description"
android:previewLayout="@layout/people_space_placeholder_layout"
android:resizeMode="horizontal|vertical"
diff --git a/packages/SystemUI/shared/lint-baseline.xml b/packages/SystemUI/shared/lint-baseline.xml
new file mode 100644
index 000000000000..ec9d8fd468a5
--- /dev/null
+++ b/packages/SystemUI/shared/lint-baseline.xml
@@ -0,0 +1,675 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.os.RemoteException#rethrowFromSystemServer`"
+ errorLine1=" throw e.rethrowFromSystemServer();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java"
+ line="90"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 26): `android.graphics.Bitmap#getHardwareBuffer`"
+ errorLine1=" mBuffer != null ? mBuffer.getHardwareBuffer() : null, mRect);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/AppTransitionAnimationSpecCompat.java"
+ line="39"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 26): `new android.graphics.ParcelableColorSpace`"
+ errorLine1=" ? new ParcelableColorSpace(ColorSpace.get(ColorSpace.Named.SRGB))"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/BitmapUtil.java"
+ line="57"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 26): `new android.graphics.ParcelableColorSpace`"
+ errorLine1=" : new ParcelableColorSpace(bitmap.getColorSpace());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/BitmapUtil.java"
+ line="58"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 26): `android.graphics.Bitmap#getHardwareBuffer`"
+ errorLine1=" bundle.putParcelable(KEY_BUFFER, bitmap.getHardwareBuffer());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/BitmapUtil.java"
+ line="61"
+ column="49"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast from `ParcelableColorSpace` to `Parcelable` requires API level 31 (current min is 26)"
+ errorLine1=" bundle.putParcelable(KEY_COLOR_SPACE, colorSpace);"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/BitmapUtil.java"
+ line="62"
+ column="47"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.graphics.Bitmap#wrapHardwareBuffer`"
+ errorLine1=" return Bitmap.wrapHardwareBuffer(Objects.requireNonNull(buffer),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/BitmapUtil.java"
+ line="84"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 26): `android.graphics.ParcelableColorSpace#getColorSpace`"
+ errorLine1=" colorSpace.getColorSpace());"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/BitmapUtil.java"
+ line="85"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java"
+ line="122"
+ column="47"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.util.ArraySet`"
+ errorLine1=" mPluginActions = new ArraySet&lt;>(mSharedPrefs.getStringSet(PLUGIN_ACTIONS, null));"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginPrefs.java"
+ line="41"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.util.ArraySet`"
+ errorLine1=" return new ArraySet&lt;>(mPluginActions);"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginPrefs.java"
+ line="45"
+ column="16"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 26): `android.graphics.Bitmap#createBitmap`"
+ errorLine1=" return Bitmap.createBitmap(picture);"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/RecentsTransition.java"
+ line="113"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Builder`"
+ errorLine1=" mSurface = new SurfaceControl.Builder()"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java"
+ line="116"
+ column="24"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setName`"
+ errorLine1=" .setName(&quot;Transition Unrotate&quot;)"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java"
+ line="117"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`"
+ errorLine1=" .setParent(parent)"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java"
+ line="119"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#build`"
+ errorLine1=" .build();"
+ errorLine2=" ~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java"
+ line="120"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`"
+ errorLine1=" t.reparent(child, mSurface);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java"
+ line="137"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" SurfaceControl.Transaction t = new SurfaceControl.Transaction();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java"
+ line="143"
+ column="44"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`"
+ errorLine1=" t.reparent(mRotateChildren.get(i), rootLeash);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java"
+ line="145"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java"
+ line="148"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(counterLauncher.mSurface, launcherLayer);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java"
+ line="200"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(counterLauncher.mSurface, info.getChanges().size() * 3);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java"
+ line="206"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(leash, info.getChanges().size() * 3 - i);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java"
+ line="216"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(wallpapersCompat[i].leash.getSurfaceControl(), 1.f);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java"
+ line="223"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(counterWallpaper.mSurface, -1);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java"
+ line="233"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java"
+ line="238"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" taskId = change.getTaskInfo() != null ? change.getTaskInfo().taskId : -1;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java"
+ line="101"
+ column="49"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#isRunning`"
+ errorLine1=" isNotInRecents = !change.getTaskInfo().isRunning;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java"
+ line="116"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#release`"
+ errorLine1=" leash.mSurfaceControl.release();"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java"
+ line="159"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#release`"
+ errorLine1=" mStartLeash.release();"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java"
+ line="161"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(change.getLeash(), info.getChanges().size() * 3 - i);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java"
+ line="97"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(wallpapers[i].leash.mSurfaceControl, 1);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java"
+ line="105"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java"
+ line="107"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#isValid`"
+ errorLine1=" return mSurfaceControl != null &amp;&amp; mSurfaceControl.isValid();"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceControlCompat.java"
+ line="41"
+ column="59"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.SurfaceControlViewHost#release`"
+ errorLine1=" mSurfaceControlViewHost.release();"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestReceiver.java"
+ line="61"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 26): `android.view.SurfaceView#getHostToken`"
+ errorLine1=" bundle.putBinder(KEY_HOST_TOKEN, surfaceView.getHostToken());"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestUtils.java"
+ line="34"
+ column="54"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceView#getSurfaceControl`"
+ errorLine1=" bundle.putParcelable(KEY_SURFACE_CONTROL, surfaceView.getSurfaceControl());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestUtils.java"
+ line="35"
+ column="63"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast from `SurfaceControl` to `Parcelable` requires API level 29 (current min is 26)"
+ errorLine1=" bundle.putParcelable(KEY_SURFACE_CONTROL, surfaceView.getSurfaceControl());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestUtils.java"
+ line="35"
+ column="51"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#isValid`"
+ errorLine1=" if (mBarrierSurfaceControl == null || !mBarrierSurfaceControl.isValid()) {"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java"
+ line="107"
+ column="79"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" Transaction t = new Transaction();"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java"
+ line="113"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java"
+ line="122"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" t.setAlpha(surface, alpha);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java"
+ line="361"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" t.setLayer(surface, layer);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java"
+ line="364"
+ column="19"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#origActivity`"
+ errorLine1=" ComponentName sourceComponent = t.origActivity != null"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java"
+ line="73"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#origActivity`"
+ errorLine1=" ? t.origActivity"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java"
+ line="75"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#taskId`"
+ errorLine1=" this.id = t.taskId;"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java"
+ line="78"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#baseIntent`"
+ errorLine1=" this.baseIntent = t.baseIntent;"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java"
+ line="80"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#taskDescription`"
+ errorLine1=" ActivityManager.TaskDescription td = taskInfo.taskDescription;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java"
+ line="242"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#topActivity`"
+ errorLine1=" taskInfo.supportsSplitScreenMultiWindow, isLocked, td, taskInfo.topActivity);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java"
+ line="246"
+ column="72"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#topActivity`"
+ errorLine1=" return info.topActivity;"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java"
+ line="49"
+ column="16"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#taskDescription`"
+ errorLine1=" return info.taskDescription;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java"
+ line="53"
+ column="16"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+ errorLine1=" onTaskMovedToFront(taskInfo.taskId);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java"
+ line="70"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.graphics.Bitmap#wrapHardwareBuffer`"
+ errorLine1=" thumbnail = Bitmap.wrapHardwareBuffer(buffer, snapshot.getColorSpace());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java"
+ line="69"
+ column="36"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 26): `android.app.WallpaperColors#getColorHints`"
+ errorLine1=" (colors.getColorHints() &amp; WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TonalCompat.java"
+ line="42"
+ column="29"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+ errorLine1=" mTransaction = new Transaction();"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java"
+ line="31"
+ column="24"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" mTransaction.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java"
+ line="35"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setBufferSize`"
+ errorLine1=" mTransaction.setBufferSize(surfaceControl.mSurfaceControl, w, h);"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java"
+ line="54"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+ errorLine1=" mTransaction.setLayer(surfaceControl.mSurfaceControl, z);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java"
+ line="59"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+ errorLine1=" mTransaction.setAlpha(surfaceControl.mSurfaceControl, alpha);"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java"
+ line="64"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+ errorLine1=" t.apply();"
+ errorLine2=" ~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/ViewRootImplCompat.java"
+ line="64"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`"
+ errorLine1=" .getFloat(Resources.getSystem().getIdentifier("
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperManagerCompat.java"
+ line="46"
+ column="18"/>
+ </issue>
+
+</issues>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
index 4f3f86aeca97..26ef1455be7d 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
@@ -42,6 +42,8 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DataClass;
import com.android.systemui.shared.recents.model.ThumbnailData;
+import java.util.concurrent.Executor;
+
/**
* Wrapper to expose RemoteTransition (shell transitions) to Launcher.
*
@@ -59,7 +61,8 @@ public class RemoteTransitionCompat implements Parcelable {
mTransition = transition;
}
- public RemoteTransitionCompat(RemoteTransitionRunner runner) {
+ public RemoteTransitionCompat(@NonNull RemoteTransitionRunner runner,
+ @NonNull Executor executor) {
mTransition = new IRemoteTransition.Stub() {
@Override
public void startAnimation(TransitionInfo info, SurfaceControl.Transaction t,
@@ -71,7 +74,7 @@ public class RemoteTransitionCompat implements Parcelable {
Log.e(TAG, "Failed to call transition finished callback", e);
}
};
- runner.startAnimation(info, t, finishAdapter);
+ executor.execute(() -> runner.startAnimation(info, t, finishAdapter));
}
};
}
diff --git a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
index ab219f36bab3..60b677a4e561 100644
--- a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
@@ -27,6 +27,7 @@ import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.util.ViewController;
import java.util.Locale;
@@ -45,6 +46,7 @@ public class AnimatableClockController extends ViewController<AnimatableClockVie
private int mLockScreenColor;
private boolean mIsDozing;
+ private boolean mIsCharging;
private float mDozeAmount;
private Locale mLocale;
@@ -56,7 +58,8 @@ public class AnimatableClockController extends ViewController<AnimatableClockVie
public AnimatableClockController(
AnimatableClockView view,
StatusBarStateController statusBarStateController,
- BroadcastDispatcher broadcastDispatcher) {
+ BroadcastDispatcher broadcastDispatcher,
+ BatteryController batteryController) {
super(view);
mStatusBarStateController = statusBarStateController;
mIsDozing = mStatusBarStateController.isDozing();
@@ -68,6 +71,16 @@ public class AnimatableClockController extends ViewController<AnimatableClockVie
R.dimen.keyguard_clock_line_spacing_scale_burmese);
mDefaultLineSpacing = getContext().getResources().getFloat(
R.dimen.keyguard_clock_line_spacing_scale);
+
+ batteryController.addCallback(new BatteryController.BatteryStateChangeCallback() {
+ @Override
+ public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
+ if (!mIsCharging && charging) {
+ mView.animateCharge(mIsDozing);
+ }
+ mIsCharging = charging;
+ }
+ });
}
private BroadcastReceiver mLocaleBroadcastReceiver = new BroadcastReceiver() {
diff --git a/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java b/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java
index c918d9871a7d..0d6f64f004f9 100644
--- a/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java
+++ b/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java
@@ -42,7 +42,9 @@ public class AnimatableClockView extends TextView {
private static final CharSequence DOUBLE_LINE_FORMAT_24_HOUR = "HH\nmm";
private static final CharSequence SINGLE_LINE_FORMAT_12_HOUR = "h:mm";
private static final CharSequence SINGLE_LINE_FORMAT_24_HOUR = "H:mm";
- private static final long ANIM_DURATION = 300;
+ private static final long DOZE_ANIM_DURATION = 300;
+ private static final long CHARGE_ANIM_DURATION_PHASE_0 = 500;
+ private static final long CHARGE_ANIM_DURATION_PHASE_1 = 1000;
private final Calendar mTime = Calendar.getInstance();
@@ -53,6 +55,7 @@ public class AnimatableClockView extends TextView {
private int mDozingColor;
private int mLockScreenColor;
private float mLineSpacingScale = 1f;
+ private int mChargeAnimationDelay = 0;
private TextAnimator mTextAnimator = null;
private Runnable mOnTextAnimatorInitialized;
@@ -79,6 +82,8 @@ public class AnimatableClockView extends TextView {
try {
mDozingWeight = ta.getInt(R.styleable.AnimatableClockView_dozeWeight, 100);
mLockScreenWeight = ta.getInt(R.styleable.AnimatableClockView_lockScreenWeight, 300);
+ mChargeAnimationDelay = ta.getInt(
+ R.styleable.AnimatableClockView_chargeAnimationDelay, 200);
} finally {
ta.recycle();
}
@@ -150,11 +155,36 @@ public class AnimatableClockView extends TextView {
mLockScreenColor = lockScreenColor;
}
+ void animateCharge(boolean isDozing) {
+ if (mTextAnimator == null || mTextAnimator.isRunning()) {
+ // Skip charge animation if dozing animation is already playing.
+ return;
+ }
+ Runnable startAnimPhase2 = () -> setTextStyle(
+ isDozing ? mDozingWeight : mLockScreenWeight/* weight */,
+ -1,
+ null,
+ true /* animate */,
+ CHARGE_ANIM_DURATION_PHASE_1,
+ 0 /* delay */,
+ null /* onAnimationEnd */);
+ setTextStyle(isDozing ? mLockScreenWeight : mDozingWeight/* weight */,
+ -1,
+ null,
+ true /* animate */,
+ CHARGE_ANIM_DURATION_PHASE_0,
+ mChargeAnimationDelay,
+ startAnimPhase2);
+ }
+
void animateDoze(boolean isDozing, boolean animate) {
setTextStyle(isDozing ? mDozingWeight : mLockScreenWeight /* weight */,
-1,
isDozing ? mDozingColor : mLockScreenColor,
- animate);
+ animate,
+ DOZE_ANIM_DURATION,
+ 0 /* delay */,
+ null /* onAnimationEnd */);
}
/**
@@ -170,15 +200,20 @@ public class AnimatableClockView extends TextView {
private void setTextStyle(
@IntRange(from = 0, to = 1000) int weight,
@FloatRange(from = 0) float textSize,
- int color,
- boolean animate) {
+ Integer color,
+ boolean animate,
+ long duration,
+ long delay,
+ Runnable onAnimationEnd) {
if (mTextAnimator != null) {
- mTextAnimator.setTextStyle(weight, textSize, color, animate, ANIM_DURATION, null);
+ mTextAnimator.setTextStyle(weight, textSize, color, animate, duration, null,
+ delay, onAnimationEnd);
} else {
// when the text animator is set, update its start values
mOnTextAnimatorInitialized =
() -> mTextAnimator.setTextStyle(
- weight, textSize, color, false, ANIM_DURATION, null);
+ weight, textSize, color, false, duration, null,
+ delay, onAnimationEnd);
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 13a84fb605f0..407146fa991c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -4,35 +4,21 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Paint;
import android.graphics.Paint.Style;
-import android.os.Build;
-import android.transition.Fade;
-import android.transition.Transition;
-import android.transition.TransitionListenerAdapter;
-import android.transition.TransitionManager;
-import android.transition.TransitionSet;
-import android.transition.TransitionValues;
import android.util.AttributeSet;
-import android.util.Log;
-import android.util.MathUtils;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
-import android.widget.TextClock;
-import android.widget.TextView;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.keyguard.dagger.KeyguardStatusViewScope;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.plugins.ClockPlugin;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -47,53 +33,21 @@ public class KeyguardClockSwitch extends RelativeLayout {
private static final String TAG = "KeyguardClockSwitch";
- /**
- * Animation fraction when text is transitioned to/from bold.
- */
- private static final float TO_BOLD_TRANSITION_FRACTION = 0.7f;
-
private static final long CLOCK_OUT_MILLIS = 150;
private static final long CLOCK_IN_MILLIS = 200;
/**
- * Layout transition that scales the default clock face.
- */
- private final Transition mTransition;
-
- private final ClockVisibilityTransition mClockTransition;
- private final ClockVisibilityTransition mBoldClockTransition;
-
- /**
* Optional/alternative clock injected via plugin.
*/
private ClockPlugin mClockPlugin;
/**
- * Default clock.
+ * Frame for small/large clocks
*/
- private TextClock mClockView;
-
- /**
- * Default clock, bold version.
- * Used to transition to bold when shrinking the default clock.
- */
- private TextClock mClockViewBold;
-
- /**
- * Frame for clock when mode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL.
- */
- private FrameLayout mNewLockscreenClockFrame;
- private FrameLayout mNewLockscreenLargeClockFrame;
-
- /**
- * Frame for default and custom clock.
- */
- private FrameLayout mSmallClockFrame;
-
- /**
- * Container for big custom clock.
- */
- private ViewGroup mBigClockContainer;
+ private FrameLayout mClockFrame;
+ private FrameLayout mLargeClockFrame;
+ private AnimatableClockView mClockView;
+ private AnimatableClockView mLargeClockView;
/**
* Status area (date and other stuff) shown below the clock. Plugin can decide whether or not to
@@ -117,40 +71,23 @@ public class KeyguardClockSwitch extends RelativeLayout {
/**
* If the Keyguard Slice has a header (big center-aligned text.)
*/
- private boolean mShowingHeader;
private boolean mSupportsDarkText;
private int[] mColorPalette;
- private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
private int mClockSwitchYAmount;
public KeyguardClockSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
-
- mClockTransition = new ClockVisibilityTransition().setCutoff(
- 1 - TO_BOLD_TRANSITION_FRACTION);
- mClockTransition.addTarget(R.id.default_clock_view);
- mBoldClockTransition = new ClockVisibilityTransition().setCutoff(
- TO_BOLD_TRANSITION_FRACTION);
- mBoldClockTransition.addTarget(R.id.default_clock_view_bold);
- mTransition = new TransitionSet()
- .setOrdering(TransitionSet.ORDERING_TOGETHER)
- .addTransition(mClockTransition)
- .addTransition(mBoldClockTransition)
- .setDuration(KeyguardSliceView.DEFAULT_ANIM_DURATION / 2)
- .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
}
/**
* Apply dp changes on font/scale change
*/
public void onDensityOrFontScaleChanged() {
- setTextSize(TypedValue.COMPLEX_UNIT_PX, mContext.getResources()
- .getDimensionPixelSize(R.dimen.widget_big_font_size));
-
- ((TextView) mNewLockscreenLargeClockFrame.getChildAt(0))
- .setTextSize(TypedValue.COMPLEX_UNIT_PX, mContext.getResources()
- .getDimensionPixelSize(R.dimen.large_clock_text_size));
+ mLargeClockView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mContext.getResources()
+ .getDimensionPixelSize(R.dimen.large_clock_text_size));
+ mClockView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mContext.getResources()
+ .getDimensionPixelSize(R.dimen.clock_text_size));
mClockSwitchYAmount = mContext.getResources().getDimensionPixelSize(
R.dimen.keyguard_clock_switch_y_shift);
@@ -163,44 +100,14 @@ public class KeyguardClockSwitch extends RelativeLayout {
return mClockPlugin != null;
}
- /**
- * Update lock screen mode for testing different layouts
- */
- public void updateLockScreenMode(int mode) {
- mLockScreenMode = mode;
- RelativeLayout.LayoutParams statusAreaLP = (RelativeLayout.LayoutParams)
- mKeyguardStatusArea.getLayoutParams();
-
- if (mode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
- final int startEndPadding = (int) TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP,
- 32,
- getResources().getDisplayMetrics());
- setPaddingRelative(startEndPadding, 0, startEndPadding, 0);
- mSmallClockFrame.setVisibility(GONE);
- mNewLockscreenClockFrame.setVisibility(VISIBLE);
- statusAreaLP.addRule(RelativeLayout.BELOW, R.id.new_lockscreen_clock_view);
- statusAreaLP.addRule(RelativeLayout.ALIGN_PARENT_START);
- } else {
- setPaddingRelative(0, 0, 0, 0);
- mSmallClockFrame.setVisibility(VISIBLE);
- mNewLockscreenClockFrame.setVisibility(GONE);
-
- statusAreaLP.removeRule(RelativeLayout.ALIGN_PARENT_START);
- statusAreaLP.addRule(RelativeLayout.BELOW, R.id.clock_view);
- }
-
- requestLayout();
- }
-
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mClockView = findViewById(R.id.default_clock_view);
- mClockViewBold = findViewById(R.id.default_clock_view_bold);
- mNewLockscreenClockFrame = findViewById(R.id.new_lockscreen_clock_view);
- mNewLockscreenLargeClockFrame = findViewById(R.id.new_lockscreen_clock_view_large);
- mSmallClockFrame = findViewById(R.id.clock_view);
+
+ mClockFrame = findViewById(R.id.lockscreen_clock_view);
+ mClockView = findViewById(R.id.animatable_clock_view);
+ mLargeClockFrame = findViewById(R.id.lockscreen_clock_view_large);
+ mLargeClockView = findViewById(R.id.animatable_clock_view_large);
mKeyguardStatusArea = findViewById(R.id.keyguard_status_area);
onDensityOrFontScaleChanged();
@@ -210,45 +117,35 @@ public class KeyguardClockSwitch extends RelativeLayout {
// Disconnect from existing plugin.
if (mClockPlugin != null) {
View smallClockView = mClockPlugin.getView();
- if (smallClockView != null && smallClockView.getParent() == mSmallClockFrame) {
- mSmallClockFrame.removeView(smallClockView);
+ if (smallClockView != null && smallClockView.getParent() == mClockFrame) {
+ mClockFrame.removeView(smallClockView);
}
- if (mBigClockContainer != null) {
- mBigClockContainer.removeAllViews();
- updateBigClockVisibility(statusBarState);
+ View bigClockView = mClockPlugin.getBigClockView();
+ if (bigClockView != null && bigClockView.getParent() == mLargeClockFrame) {
+ mLargeClockFrame.removeView(bigClockView);
}
mClockPlugin.onDestroyView();
mClockPlugin = null;
}
if (plugin == null) {
- if (mShowingHeader) {
- mClockView.setVisibility(View.GONE);
- mClockViewBold.setVisibility(View.VISIBLE);
- } else {
- mClockView.setVisibility(View.VISIBLE);
- mClockViewBold.setVisibility(View.INVISIBLE);
- }
- mKeyguardStatusArea.setVisibility(View.VISIBLE);
+ mClockView.setVisibility(View.VISIBLE);
+ mLargeClockView.setVisibility(View.VISIBLE);
return;
}
// Attach small and big clock views to hierarchy.
View smallClockView = plugin.getView();
if (smallClockView != null) {
- mSmallClockFrame.addView(smallClockView, -1,
+ mClockFrame.addView(smallClockView, -1,
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
mClockView.setVisibility(View.GONE);
- mClockViewBold.setVisibility(View.GONE);
}
View bigClockView = plugin.getBigClockView();
- if (bigClockView != null && mBigClockContainer != null) {
- mBigClockContainer.addView(bigClockView);
- updateBigClockVisibility(statusBarState);
- }
- // Hide default clock.
- if (!plugin.shouldShowStatusArea()) {
- mKeyguardStatusArea.setVisibility(View.GONE);
+ if (bigClockView != null) {
+ mLargeClockFrame.addView(bigClockView);
+ mLargeClockView.setVisibility(View.GONE);
}
+
// Initialize plugin parameters.
mClockPlugin = plugin;
mClockPlugin.setStyle(getPaint().getStyle());
@@ -259,31 +156,10 @@ public class KeyguardClockSwitch extends RelativeLayout {
}
}
- float getClockTextTopPadding() {
- Paint.FontMetrics fm = mClockView.getPaint().getFontMetrics();
- return fm.ascent - fm.top;
- }
-
- /**
- * Set container for big clock face appearing behind NSSL and KeyguardStatusView.
- */
- public void setBigClockContainer(ViewGroup container, int statusBarState) {
- if (mClockPlugin != null && container != null) {
- View bigClockView = mClockPlugin.getBigClockView();
- if (bigClockView != null) {
- container.addView(bigClockView);
- }
- }
- mBigClockContainer = container;
- updateBigClockVisibility(statusBarState);
- }
-
/**
* It will also update plugin setStyle if plugin is connected.
*/
public void setStyle(Style style) {
- mClockView.getPaint().setStyle(style);
- mClockViewBold.getPaint().setStyle(style);
if (mClockPlugin != null) {
mClockPlugin.setStyle(style);
}
@@ -293,48 +169,25 @@ public class KeyguardClockSwitch extends RelativeLayout {
* It will also update plugin setTextColor if plugin is connected.
*/
public void setTextColor(int color) {
- mClockView.setTextColor(color);
- mClockViewBold.setTextColor(color);
if (mClockPlugin != null) {
mClockPlugin.setTextColor(color);
}
}
- public void setShowCurrentUserTime(boolean showCurrentUserTime) {
- mClockView.setShowCurrentUserTime(showCurrentUserTime);
- mClockViewBold.setShowCurrentUserTime(showCurrentUserTime);
- }
-
- public void setTextSize(int unit, float size) {
- mClockView.setTextSize(unit, size);
- }
-
- public void setFormat12Hour(CharSequence format) {
- mClockView.setFormat12Hour(format);
- mClockViewBold.setFormat12Hour(format);
- }
-
- public void setFormat24Hour(CharSequence format) {
- mClockView.setFormat24Hour(format);
- mClockViewBold.setFormat24Hour(format);
- }
-
private void animateClockChange(boolean useLargeClock) {
- if (mLockScreenMode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) return;
-
if (mClockInAnim != null) mClockInAnim.cancel();
if (mClockOutAnim != null) mClockOutAnim.cancel();
View in, out;
int direction = 1;
if (useLargeClock) {
- out = mNewLockscreenClockFrame;
- in = mNewLockscreenLargeClockFrame;
+ out = mClockFrame;
+ in = mLargeClockFrame;
if (indexOfChild(in) == -1) addView(in);
direction = -1;
} else {
- in = mNewLockscreenClockFrame;
- out = mNewLockscreenLargeClockFrame;
+ in = mClockFrame;
+ out = mLargeClockFrame;
// Must remove in order for notifications to appear in the proper place
removeView(out);
@@ -381,7 +234,6 @@ public class KeyguardClockSwitch extends RelativeLayout {
if (mClockPlugin != null) {
mClockPlugin.setDarkAmount(darkAmount);
}
- updateBigClockAlpha();
}
/**
@@ -394,13 +246,6 @@ public class KeyguardClockSwitch extends RelativeLayout {
animateClockChange(!hasVisibleNotifications);
mHasVisibleNotifications = hasVisibleNotifications;
- if (mDarkAmount == 0f && mBigClockContainer != null) {
- // Starting a fade transition since the visibility of the big clock will change.
- TransitionManager.beginDelayedTransition(mBigClockContainer,
- new Fade().setDuration(KeyguardSliceView.DEFAULT_ANIM_DURATION / 2).addTarget(
- mBigClockContainer));
- }
- updateBigClockAlpha();
}
public Paint getPaint() {
@@ -433,15 +278,9 @@ public class KeyguardClockSwitch extends RelativeLayout {
* Refresh the time of the clock, due to either time tick broadcast or doze time tick alarm.
*/
public void refresh() {
- mClockView.refreshTime();
- mClockViewBold.refreshTime();
if (mClockPlugin != null) {
mClockPlugin.onTimeTick();
}
- if (Build.IS_DEBUGGABLE) {
- // Log for debugging b/130888082 (sysui waking up, but clock not updating)
- Log.d(TAG, "Updating clock: " + mClockView.getText());
- }
}
/**
@@ -472,240 +311,14 @@ public class KeyguardClockSwitch extends RelativeLayout {
}
}
- void updateBigClockVisibility(int statusBarState) {
- if (mBigClockContainer == null) {
- return;
- }
- final boolean inDisplayState = statusBarState == StatusBarState.KEYGUARD
- || statusBarState == StatusBarState.SHADE_LOCKED;
- final int visibility = !mShowingHeader && inDisplayState
- && mBigClockContainer.getChildCount() != 0 ? View.VISIBLE : View.GONE;
- if (mBigClockContainer.getVisibility() != visibility) {
- mBigClockContainer.setVisibility(visibility);
- }
- }
-
- private void updateBigClockAlpha() {
- if (mBigClockContainer != null) {
- final float alpha = mHasVisibleNotifications ? mDarkAmount : 1f;
- mBigClockContainer.setAlpha(alpha);
- if (alpha == 0f) {
- mBigClockContainer.setVisibility(INVISIBLE);
- } else if (mBigClockContainer.getVisibility() == INVISIBLE) {
- mBigClockContainer.setVisibility(VISIBLE);
- }
- }
- }
-
- /**
- * Sets if the keyguard slice is showing a center-aligned header. We need a smaller clock in
- * these cases.
- */
- void setKeyguardShowingHeader(boolean hasHeader) {
- if (mLockScreenMode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL) {
- hasHeader = false;
- }
-
- if (mShowingHeader == hasHeader) {
- return;
- }
- mShowingHeader = hasHeader;
- if (hasCustomClock()) {
- return;
- }
-
- float smallFontSize = mContext.getResources().getDimensionPixelSize(
- R.dimen.widget_small_font_size);
- float bigFontSize = mContext.getResources().getDimensionPixelSize(
- R.dimen.widget_big_font_size);
- mClockTransition.setScale(smallFontSize / bigFontSize);
- mBoldClockTransition.setScale(bigFontSize / smallFontSize);
-
- // End any current transitions before starting a new transition so that the new transition
- // starts from a good state instead of a potentially bad intermediate state arrived at
- // during a transition animation.
- TransitionManager.endTransitions((ViewGroup) mClockView.getParent());
-
- if (hasHeader) {
- // After the transition, make the default clock GONE so that it doesn't make the
- // KeyguardStatusView appear taller in KeyguardClockPositionAlgorithm and elsewhere.
- mTransition.addListener(new TransitionListenerAdapter() {
- @Override
- public void onTransitionEnd(Transition transition) {
- super.onTransitionEnd(transition);
- // Check that header is actually showing. I saw issues where this event was
- // fired after the big clock transitioned back to visible, which causes the time
- // to completely disappear.
- if (mShowingHeader) {
- mClockView.setVisibility(View.GONE);
- }
- transition.removeListener(this);
- }
- });
- }
-
- TransitionManager.beginDelayedTransition((ViewGroup) mClockView.getParent(), mTransition);
- mClockView.setVisibility(hasHeader ? View.INVISIBLE : View.VISIBLE);
- mClockViewBold.setVisibility(hasHeader ? View.VISIBLE : View.INVISIBLE);
- int paddingBottom = mContext.getResources().getDimensionPixelSize(hasHeader
- ? R.dimen.widget_vertical_padding_clock : R.dimen.title_clock_padding);
- mClockView.setPadding(mClockView.getPaddingLeft(), mClockView.getPaddingTop(),
- mClockView.getPaddingRight(), paddingBottom);
- mClockViewBold.setPadding(mClockViewBold.getPaddingLeft(), mClockViewBold.getPaddingTop(),
- mClockViewBold.getPaddingRight(), paddingBottom);
- }
-
- /**
- * Hide big clock if the keyguard slice is showing a header, need to reduce visual clutter in
- * these cases.
- */
- public void setKeyguardHidingBigClock(boolean hasHeader) {
- if (mBigClockContainer != null) {
- mBigClockContainer.setVisibility(hasHeader ? View.GONE : View.VISIBLE);
- }
- }
-
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("KeyguardClockSwitch:");
pw.println(" mClockPlugin: " + mClockPlugin);
- pw.println(" mClockView: " + mClockView);
- pw.println(" mClockViewBold: " + mClockViewBold);
- pw.println(" mSmallClockFrame: " + mSmallClockFrame);
- pw.println(" mBigClockContainer: " + mBigClockContainer);
+ pw.println(" mClockFrame: " + mClockFrame);
+ pw.println(" mLargeClockFrame: " + mLargeClockFrame);
pw.println(" mKeyguardStatusArea: " + mKeyguardStatusArea);
pw.println(" mDarkAmount: " + mDarkAmount);
- pw.println(" mShowingHeader: " + mShowingHeader);
pw.println(" mSupportsDarkText: " + mSupportsDarkText);
pw.println(" mColorPalette: " + Arrays.toString(mColorPalette));
}
-
- /**
- * {@link Visibility} transformation that scales the view while it is disappearing/appearing and
- * transitions suddenly at a cutoff fraction during the animation.
- */
- private class ClockVisibilityTransition extends android.transition.Visibility {
-
- private static final String PROPNAME_VISIBILITY = "systemui:keyguard:visibility";
-
- private float mCutoff;
- private float mScale;
-
- /**
- * Constructs a transition that switches between visible/invisible at a cutoff and scales in
- * size while appearing/disappearing.
- */
- ClockVisibilityTransition() {
- setCutoff(1f);
- setScale(1f);
- }
-
- /**
- * Sets the transition point between visible/invisible.
- *
- * @param cutoff The fraction in [0, 1] when the view switches between visible/invisible.
- * @return This transition object
- */
- public ClockVisibilityTransition setCutoff(float cutoff) {
- mCutoff = cutoff;
- return this;
- }
-
- /**
- * Sets the scale factor applied while appearing/disappearing.
- *
- * @param scale Scale factor applied while appearing/disappearing. When factor is less than
- * one, the view will shrink while disappearing. When it is greater than one,
- * the view will expand while disappearing.
- * @return This transition object
- */
- public ClockVisibilityTransition setScale(float scale) {
- mScale = scale;
- return this;
- }
-
- @Override
- public void captureStartValues(TransitionValues transitionValues) {
- super.captureStartValues(transitionValues);
- captureVisibility(transitionValues);
- }
-
- @Override
- public void captureEndValues(TransitionValues transitionValues) {
- super.captureStartValues(transitionValues);
- captureVisibility(transitionValues);
- }
-
- private void captureVisibility(TransitionValues transitionValues) {
- transitionValues.values.put(PROPNAME_VISIBILITY,
- transitionValues.view.getVisibility());
- }
-
- @Override
- public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
- TransitionValues endValues) {
- if (!sceneRoot.isShown()) {
- return null;
- }
- final float cutoff = mCutoff;
- final int startVisibility = View.INVISIBLE;
- final int endVisibility = (int) endValues.values.get(PROPNAME_VISIBILITY);
- final float startScale = mScale;
- final float endScale = 1f;
- return createAnimator(view, cutoff, startVisibility, endVisibility, startScale,
- endScale);
- }
-
- @Override
- public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
- TransitionValues endValues) {
- if (!sceneRoot.isShown()) {
- return null;
- }
- final float cutoff = 1f - mCutoff;
- final int startVisibility = View.VISIBLE;
- final int endVisibility = (int) endValues.values.get(PROPNAME_VISIBILITY);
- final float startScale = 1f;
- final float endScale = mScale;
- return createAnimator(view, cutoff, startVisibility, endVisibility, startScale,
- endScale);
- }
-
- private Animator createAnimator(View view, float cutoff, int startVisibility,
- int endVisibility, float startScale, float endScale) {
- view.setPivotY(view.getHeight() - view.getPaddingBottom());
- ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
- animator.addUpdateListener(animation -> {
- final float fraction = animation.getAnimatedFraction();
- if (fraction > cutoff) {
- view.setVisibility(endVisibility);
- }
- final float scale = MathUtils.lerp(startScale, endScale, fraction);
- view.setScaleX(scale);
- view.setScaleY(scale);
- });
- animator.addListener(new KeepAwakeAnimationListener(getContext()) {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- view.setVisibility(startVisibility);
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- animation.removeListener(this);
- }
- });
- addListener(new TransitionListenerAdapter() {
- @Override
- public void onTransitionEnd(Transition transition) {
- view.setVisibility(endVisibility);
- view.setScaleX(1f);
- view.setScaleY(1f);
- transition.removeListener(this);
- }
- });
- return animator;
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 0675200f81e2..032ed7da0a46 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -16,15 +16,21 @@
package com.android.keyguard;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+
import android.app.WallpaperManager;
+import android.app.smartspace.SmartspaceConfig;
+import android.app.smartspace.SmartspaceManager;
+import android.app.smartspace.SmartspaceSession;
import android.content.ContentResolver;
+import android.content.Context;
import android.content.res.Resources;
-import android.provider.Settings;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.view.View;
-import android.view.ViewGroup;
import android.widget.FrameLayout;
+import android.widget.RelativeLayout;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.keyguard.clock.ClockManager;
@@ -32,17 +38,23 @@ import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.plugins.BcSmartspaceDataPlugin;
import com.android.systemui.plugins.ClockPlugin;
+import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.NotificationIconContainer;
+import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.util.ViewController;
import java.util.Locale;
import java.util.TimeZone;
+import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -59,24 +71,22 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
private final KeyguardSliceViewController mKeyguardSliceViewController;
private final NotificationIconAreaController mNotificationIconAreaController;
private final BroadcastDispatcher mBroadcastDispatcher;
+ private final BatteryController mBatteryController;
/**
- * Gradient clock for usage when mode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL.
+ * Clock for both small and large sizes
*/
- private AnimatableClockController mNewLockScreenClockViewController;
- private FrameLayout mNewLockScreenClockFrame;
- private AnimatableClockController mNewLockScreenLargeClockViewController;
- private FrameLayout mNewLockScreenLargeClockFrame;
-
- private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
-
- private final StatusBarStateController.StateListener mStateListener =
- new StatusBarStateController.StateListener() {
- @Override
- public void onStateChanged(int newState) {
- mView.updateBigClockVisibility(newState);
- }
- };
+ private AnimatableClockController mClockViewController;
+ private FrameLayout mClockFrame;
+ private AnimatableClockController mLargeClockViewController;
+ private FrameLayout mLargeClockFrame;
+
+ private PluginManager mPluginManager;
+ private boolean mIsSmartspaceEnabled;
+ PluginListener mPluginListener;
+ private Executor mUiExecutor;
+ private SmartspaceSession mSmartspaceSession;
+ private SmartspaceSession.Callback mSmartspaceCallback;
/**
* Listener for changes to the color palette.
@@ -94,7 +104,9 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
};
private ClockManager.ClockChangedListener mClockChangedListener = this::setClockPlugin;
- private String mTimeFormat;
+
+ // If set, will replace keyguard_status_area
+ private BcSmartspaceDataPlugin.SmartspaceView mSmartspaceView;
@Inject
public KeyguardClockSwitchController(
@@ -105,7 +117,11 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
KeyguardSliceViewController keyguardSliceViewController,
NotificationIconAreaController notificationIconAreaController,
ContentResolver contentResolver,
- BroadcastDispatcher broadcastDispatcher) {
+ BroadcastDispatcher broadcastDispatcher,
+ PluginManager pluginManager,
+ FeatureFlags featureFlags,
+ @Main Executor uiExecutor,
+ BatteryController batteryController) {
super(keyguardClockSwitch);
mResources = resources;
mStatusBarStateController = statusBarStateController;
@@ -114,7 +130,10 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
mKeyguardSliceViewController = keyguardSliceViewController;
mNotificationIconAreaController = notificationIconAreaController;
mBroadcastDispatcher = broadcastDispatcher;
- mTimeFormat = Settings.System.getString(contentResolver, Settings.System.TIME_12_24);
+ mPluginManager = pluginManager;
+ mIsSmartspaceEnabled = featureFlags.isSmartspaceEnabled();
+ mUiExecutor = uiExecutor;
+ mBatteryController = batteryController;
}
/**
@@ -130,13 +149,90 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
if (CUSTOM_CLOCKS_ENABLED) {
mClockManager.addOnClockChangedListener(mClockChangedListener);
}
- refreshFormat();
- mStatusBarStateController.addCallback(mStateListener);
mColorExtractor.addOnColorsChangedListener(mColorsListener);
mView.updateColors(getGradientColors());
updateAodIcons();
- mNewLockScreenClockFrame = mView.findViewById(R.id.new_lockscreen_clock_view);
- mNewLockScreenLargeClockFrame = mView.findViewById(R.id.new_lockscreen_clock_view_large);
+
+ mClockFrame = mView.findViewById(R.id.lockscreen_clock_view);
+ mLargeClockFrame = mView.findViewById(R.id.lockscreen_clock_view_large);
+
+ mClockViewController =
+ new AnimatableClockController(
+ mView.findViewById(R.id.animatable_clock_view),
+ mStatusBarStateController,
+ mBroadcastDispatcher,
+ mBatteryController);
+ mClockViewController.init();
+
+ mLargeClockViewController =
+ new AnimatableClockController(
+ mView.findViewById(R.id.animatable_clock_view_large),
+ mStatusBarStateController,
+ mBroadcastDispatcher,
+ mBatteryController);
+ mLargeClockViewController.init();
+
+ // If a smartspace plugin is detected, replace the existing smartspace
+ // (keyguard_status_area), and initialize a new session
+ mPluginListener = new PluginListener<BcSmartspaceDataPlugin>() {
+
+ @Override
+ public void onPluginConnected(BcSmartspaceDataPlugin plugin, Context pluginContext) {
+ if (!mIsSmartspaceEnabled) return;
+
+ View ksa = mView.findViewById(R.id.keyguard_status_area);
+ int ksaIndex = mView.indexOfChild(ksa);
+ ksa.setVisibility(View.GONE);
+
+ mSmartspaceView = plugin.getView(mView);
+ mSmartspaceView.registerDataProvider(plugin);
+ View asView = (View) mSmartspaceView;
+
+ RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
+ MATCH_PARENT, WRAP_CONTENT);
+ lp.addRule(RelativeLayout.BELOW, R.id.lockscreen_clock_view);
+
+ mView.addView(asView, ksaIndex, lp);
+ int padding = getContext().getResources()
+ .getDimensionPixelSize(R.dimen.below_clock_padding_start);
+ asView.setPadding(padding, 0, padding, 0);
+
+ View nic = mView.findViewById(
+ com.android.systemui.R.id.left_aligned_notification_icon_container);
+ lp = (RelativeLayout.LayoutParams) nic.getLayoutParams();
+ lp.addRule(RelativeLayout.BELOW, asView.getId());
+ nic.setLayoutParams(lp);
+
+ createSmartspaceSession(plugin);
+ }
+
+ @Override
+ public void onPluginDisconnected(BcSmartspaceDataPlugin plugin) {
+ if (!mIsSmartspaceEnabled) return;
+
+ mView.removeView((View) mSmartspaceView);
+ mView.findViewById(R.id.keyguard_status_area).setVisibility(View.VISIBLE);
+
+ View nic = mView.findViewById(
+ com.android.systemui.R.id.left_aligned_notification_icon_container);
+ RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)
+ nic.getLayoutParams();
+ lp.addRule(RelativeLayout.BELOW, R.id.keyguard_status_area);
+ nic.setLayoutParams(lp);
+
+ mSmartspaceView = null;
+ }
+
+ private void createSmartspaceSession(BcSmartspaceDataPlugin plugin) {
+ mSmartspaceSession = getContext().getSystemService(SmartspaceManager.class)
+ .createSmartspaceSession(
+ new SmartspaceConfig.Builder(getContext(), "lockscreen").build());
+ mSmartspaceCallback = targets -> plugin.onTargetsAvailable(targets);
+ mSmartspaceSession.registerSmartspaceUpdates(mUiExecutor, mSmartspaceCallback);
+ mSmartspaceSession.requestSmartspaceUpdate();
+ }
+ };
+ mPluginManager.addPluginListener(mPluginListener, BcSmartspaceDataPlugin.class, false);
}
@Override
@@ -144,9 +240,15 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
if (CUSTOM_CLOCKS_ENABLED) {
mClockManager.removeOnClockChangedListener(mClockChangedListener);
}
- mStatusBarStateController.removeCallback(mStateListener);
mColorExtractor.removeOnColorsChangedListener(mColorsListener);
mView.setClockPlugin(null, mStatusBarStateController.getState());
+
+ if (mSmartspaceSession != null) {
+ mSmartspaceSession.unregisterSmartspaceUpdates(mSmartspaceCallback);
+ mSmartspaceSession.destroy();
+ mSmartspaceSession = null;
+ }
+ mPluginManager.removePluginListener(mPluginListener);
}
/**
@@ -157,13 +259,6 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
}
/**
- * Set container for big clock face appearing behind NSSL and KeyguardStatusView.
- */
- public void setBigClockContainer(ViewGroup bigClockContainer) {
- mView.setBigClockContainer(bigClockContainer, mStatusBarStateController.getState());
- }
-
- /**
* Set whether or not the lock screen is showing notifications.
*/
public void setHasVisibleNotifications(boolean hasVisibleNotifications) {
@@ -198,9 +293,9 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
* Refresh clock. Called in response to TIME_TICK broadcasts.
*/
void refresh() {
- if (mNewLockScreenClockViewController != null) {
- mNewLockScreenClockViewController.refreshTime();
- mNewLockScreenLargeClockViewController.refreshTime();
+ if (mClockViewController != null) {
+ mClockViewController.refreshTime();
+ mLargeClockViewController.refreshTime();
}
mView.refresh();
@@ -214,81 +309,45 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
*/
void updatePosition(int x, float scale, AnimationProperties props, boolean animate) {
x = getCurrentLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? -x : x;
- if (mNewLockScreenClockFrame != null) {
- PropertyAnimator.setProperty(mNewLockScreenClockFrame, AnimatableProperty.TRANSLATION_X,
+
+ PropertyAnimator.setProperty(mClockFrame, AnimatableProperty.TRANSLATION_X,
+ x, props, animate);
+ PropertyAnimator.setProperty(mLargeClockFrame, AnimatableProperty.SCALE_X,
+ scale, props, animate);
+ PropertyAnimator.setProperty(mLargeClockFrame, AnimatableProperty.SCALE_Y,
+ scale, props, animate);
+
+ if (mSmartspaceView != null) {
+ PropertyAnimator.setProperty((View) mSmartspaceView, AnimatableProperty.TRANSLATION_X,
x, props, animate);
- PropertyAnimator.setProperty(mNewLockScreenLargeClockFrame, AnimatableProperty.SCALE_X,
- scale, props, animate);
- PropertyAnimator.setProperty(mNewLockScreenLargeClockFrame, AnimatableProperty.SCALE_Y,
- scale, props, animate);
}
+
mKeyguardSliceViewController.updatePosition(x, props, animate);
mNotificationIconAreaController.updatePosition(x, props, animate);
}
- /**
- * Update lockscreen mode that may change clock display.
- */
- void updateLockScreenMode(int mode) {
- mLockScreenMode = mode;
- if (mode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
- if (mNewLockScreenClockViewController == null) {
- mNewLockScreenClockViewController =
- new AnimatableClockController(
- mView.findViewById(R.id.animatable_clock_view),
- mStatusBarStateController,
- mBroadcastDispatcher);
- mNewLockScreenClockViewController.init();
- mNewLockScreenLargeClockViewController =
- new AnimatableClockController(
- mView.findViewById(R.id.animatable_clock_view_large),
- mStatusBarStateController,
- mBroadcastDispatcher);
- mNewLockScreenLargeClockViewController.init();
- }
- } else {
- mNewLockScreenClockViewController = null;
- mNewLockScreenLargeClockViewController = null;
- }
- mView.updateLockScreenMode(mLockScreenMode);
- updateAodIcons();
- }
-
void updateTimeZone(TimeZone timeZone) {
mView.onTimeZoneChanged(timeZone);
- if (mNewLockScreenClockViewController != null) {
- mNewLockScreenClockViewController.onTimeZoneChanged(timeZone);
- mNewLockScreenLargeClockViewController.onTimeZoneChanged(timeZone);
+ if (mClockViewController != null) {
+ mClockViewController.onTimeZoneChanged(timeZone);
+ mLargeClockViewController.onTimeZoneChanged(timeZone);
}
}
void refreshFormat(String timeFormat) {
- mTimeFormat = timeFormat;
- Patterns.update(mResources);
- mView.setFormat12Hour(Patterns.sClockView12);
- mView.setFormat24Hour(Patterns.sClockView24);
- mView.onTimeFormatChanged(mTimeFormat);
- if (mNewLockScreenClockViewController != null) {
- mNewLockScreenClockViewController.refreshFormat();
- mNewLockScreenLargeClockViewController.refreshFormat();
+ if (mClockViewController != null) {
+ mClockViewController.refreshFormat();
+ mLargeClockViewController.refreshFormat();
}
}
- void refreshFormat() {
- refreshFormat(mTimeFormat);
- }
-
private void updateAodIcons() {
NotificationIconContainer nic = (NotificationIconContainer)
mView.findViewById(
com.android.systemui.R.id.left_aligned_notification_icon_container);
- if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
- // alt icon area is set in KeyguardClockSwitchController
- mNotificationIconAreaController.setupAodIcons(nic, mLockScreenMode);
- } else {
- nic.setVisibility(View.GONE);
- }
+ // alt icon area is set in KeyguardClockSwitchController
+ mNotificationIconAreaController.setupAodIcons(nic);
}
private void setClockPlugin(ClockPlugin plugin) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
index cd9627f5bae3..90c1e402d248 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
@@ -43,8 +43,8 @@ import androidx.annotation.Nullable;
import com.android.internal.widget.LockscreenCredential;
import com.android.internal.widget.TextViewInputDisabler;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
/**
* Displays an alphanumeric (latin-1) key entry for the user to enter
* an unlock password
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 7ed63375a334..54ecf955ed11 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -53,8 +53,8 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
import com.android.systemui.Gefingerpoken;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import java.util.ArrayList;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index 96e69ad019b9..428006ebf446 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -49,8 +49,8 @@ import androidx.slice.widget.SliceContent;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.ColorUtils;
import com.android.settingslib.Utils;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;
import java.io.FileDescriptor;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 5db4f9e61140..9df7734a385f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -44,7 +44,6 @@ import java.io.PrintWriter;
* - keyguard clock
* - logout button (on certain managed devices)
* - owner information (if set)
- * - notification icons (shown on AOD)
*/
public class KeyguardStatusView extends GridLayout {
private static final boolean DEBUG = KeyguardConstants.DEBUG;
@@ -59,7 +58,6 @@ public class KeyguardStatusView extends GridLayout {
private TextView mOwnerInfo;
private boolean mCanShowOwnerInfo = true; // by default, try to show the owner information here
private KeyguardSliceView mKeyguardSlice;
- private View mNotificationIcons;
private Runnable mPendingMarqueeStart;
private Handler mHandler;
@@ -132,13 +130,11 @@ public class KeyguardStatusView extends GridLayout {
protected void onFinishInflate() {
super.onFinishInflate();
mLogoutView = findViewById(R.id.logout);
- mNotificationIcons = findViewById(R.id.clock_notification_icon_container);
if (mLogoutView != null) {
mLogoutView.setOnClickListener(this::onLogoutClicked);
}
mClockView = findViewById(R.id.keyguard_clock_container);
- mClockView.setShowCurrentUserTime(true);
if (KeyguardClockAccessibilityDelegate.isNeeded(mContext)) {
mClockView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
}
@@ -161,22 +157,10 @@ public class KeyguardStatusView extends GridLayout {
*/
private void onSliceContentChanged() {
final boolean hasHeader = mKeyguardSlice.hasHeader();
- mClockView.setKeyguardShowingHeader(hasHeader);
if (mShowingHeader == hasHeader) {
return;
}
mShowingHeader = hasHeader;
- if (mNotificationIcons != null) {
- // Update top margin since header has appeared/disappeared.
- MarginLayoutParams params = (MarginLayoutParams) mNotificationIcons.getLayoutParams();
- params.setMargins(params.leftMargin,
- hasHeader ? mIconTopMarginWithHeader : mIconTopMargin,
- params.rightMargin,
- params.bottomMargin);
- mNotificationIcons.setLayoutParams(params);
- }
-
- mClockView.setKeyguardHidingBigClock(hasHeader);
}
@Override
@@ -293,13 +277,6 @@ public class KeyguardStatusView extends GridLayout {
int expanded = mOwnerInfo.getBottom() + mOwnerInfo.getPaddingBottom();
int toRemove = (int) ((expanded - collapsed) * ratio);
setBottom(getMeasuredHeight() - toRemove);
- if (mNotificationIcons != null) {
- // We're using scrolling in order not to overload the translation which is used
- // when appearing the icons
- mNotificationIcons.setScrollY(toRemove);
- }
- } else if (mNotificationIcons != null){
- mNotificationIcons.setScrollY(0);
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index 31ec00378135..fc80dbe021a7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -18,15 +18,12 @@ package com.android.keyguard;
import android.os.UserHandle;
import android.util.Slog;
-import android.view.View;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.statusbar.phone.NotificationIconAreaController;
-import com.android.systemui.statusbar.phone.NotificationIconContainer;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.ViewController;
@@ -49,7 +46,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
private final KeyguardClockSwitchController mKeyguardClockSwitchController;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final ConfigurationController mConfigurationController;
- private final NotificationIconAreaController mNotificationIconAreaController;
private final DozeParameters mDozeParameters;
private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
@@ -63,14 +59,12 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
KeyguardStateController keyguardStateController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
ConfigurationController configurationController,
- NotificationIconAreaController notificationIconAreaController,
DozeParameters dozeParameters) {
super(keyguardStatusView);
mKeyguardSliceViewController = keyguardSliceViewController;
mKeyguardClockSwitchController = keyguardClockSwitchController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mConfigurationController = configurationController;
- mNotificationIconAreaController = notificationIconAreaController;
mDozeParameters = dozeParameters;
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
dozeParameters);
@@ -87,7 +81,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
protected void onViewAttached() {
mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
mConfigurationController.addCallback(mConfigurationListener);
- updateAodIcons();
}
@Override
@@ -237,17 +230,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
mKeyguardClockSwitchController.refresh();
}
- private void updateAodIcons() {
- NotificationIconContainer nic = (NotificationIconContainer)
- mView.findViewById(com.android.systemui.R.id.clock_notification_icon_container);
- if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL) {
- // alternate icon area is set in KeyguardClockSwitchController
- mNotificationIconAreaController.setupAodIcons(nic, mLockScreenMode);
- } else {
- nic.setVisibility(View.GONE);
- }
- }
-
private boolean shouldShowLogout() {
return mKeyguardUpdateMonitor.isLogoutEnabled()
&& KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM;
@@ -271,16 +253,9 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
@Override
public void onLockScreenModeChanged(int mode) {
mLockScreenMode = mode;
- mKeyguardClockSwitchController.updateLockScreenMode(mode);
mKeyguardSliceViewController.updateLockScreenMode(mode);
- if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
- mView.setCanShowOwnerInfo(false);
- mView.updateLogoutView(false);
- } else {
- mView.setCanShowOwnerInfo(true);
- mView.updateLogoutView(false);
- }
- updateAodIcons();
+ mView.setCanShowOwnerInfo(false);
+ mView.updateLogoutView(false);
}
@Override
@@ -294,11 +269,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
}
@Override
- public void onTimeFormatChanged(String timeFormat) {
- mKeyguardClockSwitchController.refreshFormat(timeFormat);
- }
-
- @Override
public void onKeyguardVisibilityChanged(boolean showing) {
if (showing) {
if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing);
@@ -320,7 +290,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
@Override
public void onUserSwitchComplete(int userId) {
- mKeyguardClockSwitchController.refreshFormat();
mView.updateOwnerInfo();
mView.updateLogoutView(shouldShowLogout());
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index b4c6321fe191..67ee1f45048e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -2116,6 +2116,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* If face auth is allows to scan on this exact moment.
*/
public boolean shouldListenForFace() {
+ if (mFaceManager == null) {
+ // Device does not have face auth
+ return false;
+ }
+
final boolean statusBarShadeLocked = mStatusBarState == StatusBarState.SHADE_LOCKED;
final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep
&& !statusBarShadeLocked;
@@ -2137,8 +2142,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
// Scan even when encrypted or timeout to show a preemptive bouncer when bypassing.
// Lock-down mode shouldn't scan, since it is more explicit.
- boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass && !mBouncer)
- && !isLockDown;
+ boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass && !mBouncer);
+
+ // If the device supports face detection (without authentication), allow it to happen
+ // if the device is in lockdown mode. Otherwise, prevent scanning.
+ boolean supportsDetectOnly = !mFaceSensorProperties.isEmpty()
+ && mFaceSensorProperties.get(0).supportsFaceDetection;
+ if (isLockDown && !supportsDetectOnly) {
+ strongAuthAllowsScanning = false;
+ }
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
index 724e1f660fb9..947f14138cd7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
@@ -20,7 +20,7 @@ import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import android.view.View;
-import com.android.systemui.Interpolators;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.DozeParameters;
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 7329071169cc..66ea2ad001fd 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -199,14 +199,14 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
}
private void updateVisibility() {
- if (!mIsKeyguardShowing) {
+ if (!mIsKeyguardShowing || (!mUdfpsEnrolled && !mFaceAuthEnrolled)) {
mView.setVisibility(View.INVISIBLE);
return;
}
// these three states are mutually exclusive:
mShowButton = mUdfpsEnrolled && !mCanDismissLockScreen && !mRunningFPS && isLockScreen();
- mShowUnlockIcon = mCanDismissLockScreen && isLockScreen();
+ mShowUnlockIcon = mFaceAuthEnrolled & mCanDismissLockScreen && isLockScreen();
mShowLockIcon = !mUdfpsEnrolled && !mCanDismissLockScreen && isLockScreen()
&& mFaceAuthEnrolled;
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
index 6cee4a4d4ad7..570854ecaa36 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
@@ -27,8 +27,8 @@ import android.view.ContextThemeWrapper;
import androidx.annotation.StyleRes;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
/**
* Provides background color and radius animations for key pad buttons.
diff --git a/packages/SystemUI/src/com/android/keyguard/TextAnimator.kt b/packages/SystemUI/src/com/android/keyguard/TextAnimator.kt
index 5735a4fc0172..cdb39ef216bc 100644
--- a/packages/SystemUI/src/com/android/keyguard/TextAnimator.kt
+++ b/packages/SystemUI/src/com/android/keyguard/TextAnimator.kt
@@ -65,7 +65,9 @@ class TextAnimator(
invalidateCallback()
}
addListener(object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator?) = textInterpolator.rebase()
+ override fun onAnimationEnd(animation: Animator?) {
+ textInterpolator.rebase()
+ }
override fun onAnimationCancel(animation: Animator?) = textInterpolator.rebase()
})
}
@@ -74,6 +76,10 @@ class TextAnimator(
textInterpolator.layout = layout
}
+ fun isRunning(): Boolean {
+ return animator.isRunning
+ }
+
fun draw(c: Canvas) = textInterpolator.draw(c)
/**
@@ -101,7 +107,9 @@ class TextAnimator(
color: Int? = null,
animate: Boolean = true,
duration: Long = -1L,
- interpolator: TimeInterpolator? = null
+ interpolator: TimeInterpolator? = null,
+ delay: Long = 0,
+ onAnimationEnd: Runnable? = null
) {
if (animate) {
animator.cancel()
@@ -120,12 +128,25 @@ class TextAnimator(
textInterpolator.onTargetPaintModified()
if (animate) {
+ animator.startDelay = delay
animator.duration = if (duration == -1L) {
DEFAULT_ANIMATION_DURATION
} else {
duration
}
interpolator?.let { animator.interpolator = it }
+ if (onAnimationEnd != null) {
+ val listener = object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator?) {
+ onAnimationEnd.run()
+ animator.removeListener(this)
+ }
+ override fun onAnimationCancel(animation: Animator?) {
+ animator.removeListener(this)
+ }
+ }
+ animator.addListener(listener)
+ }
animator.start()
} else {
// No animation is requested, thus set base and target state to the same state.
diff --git a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
index 5507ffabc3a0..983b1bb63913 100644
--- a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
@@ -20,9 +20,9 @@ import android.view.View;
import androidx.annotation.Nullable;
+import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.animation.ActivityLaunchAnimator;
import com.android.systemui.statusbar.phone.StatusBar;
import java.util.Optional;
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index ac99f73f7cb9..54e78cf0ab74 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -50,6 +50,7 @@ import android.widget.TextView;
import androidx.annotation.StyleRes;
import com.android.settingslib.graph.ThemedBatteryDrawable;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 721b7586240c..c8e674171b6e 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -198,8 +198,8 @@ public class ImageWallpaper extends WallpaperService {
}
mImgHeight = b.getHeight();
mImgWidth = b.getWidth();
- mMiniBitmap = Bitmap.createScaledBitmap(b, Math.round(scale * b.getWidth()),
- Math.round(scale * b.getHeight()), false);
+ mMiniBitmap = Bitmap.createScaledBitmap(b, (int) Math.ceil(scale * b.getWidth()),
+ (int) Math.ceil(scale * b.getHeight()), false);
computeAndNotifyLocalColors(mLocalColorsToAdd, mMiniBitmap);
mLocalColorsToAdd.clear();
});
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index d3ac9accfdaf..5fa98bccfc69 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -82,6 +82,7 @@ import androidx.annotation.VisibleForTesting;
import com.android.internal.util.Preconditions;
import com.android.systemui.RegionInterceptingFrameLayout.RegionInterceptableView;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index fba34e0b8ad3..b0f4da251208 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -36,6 +36,7 @@ import android.view.View;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 9d00262436e5..cc167b928c3c 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -46,6 +46,7 @@ public class SystemUIFactory {
private GlobalRootComponent mRootComponent;
private WMComponent mWMComponent;
private SysUIComponent mSysUIComponent;
+ private boolean mInitializeComponents;
public static <T extends SystemUIFactory> T getInstance() {
return (T) mFactory;
@@ -88,13 +89,13 @@ public class SystemUIFactory {
public void init(Context context, boolean fromTest)
throws ExecutionException, InterruptedException {
// Only initialize components for the main system ui process running as the primary user
- final boolean initializeComponents = !fromTest
+ mInitializeComponents = !fromTest
&& android.os.Process.myUserHandle().isSystem()
&& ActivityThread.currentProcessName().equals(ActivityThread.currentPackageName());
mRootComponent = buildGlobalRootComponent(context);
// Stand up WMComponent
mWMComponent = mRootComponent.getWMComponentBuilder().build();
- if (initializeComponents) {
+ if (mInitializeComponents) {
// Only initialize when not starting from tests since this currently initializes some
// components that shouldn't be run in the test environment
mWMComponent.init();
@@ -102,7 +103,7 @@ public class SystemUIFactory {
// And finally, retrieve whatever SysUI needs from WMShell and build SysUI.
SysUIComponent.Builder builder = mRootComponent.getSysUIComponent();
- if (initializeComponents) {
+ if (mInitializeComponents) {
// Only initialize when not starting from tests since this currently initializes some
// components that shouldn't be run in the test environment
builder = prepareSysUIComponentBuilder(builder, mWMComponent)
@@ -134,7 +135,7 @@ public class SystemUIFactory {
.setStartingSurface(Optional.ofNullable(null));
}
mSysUIComponent = builder.build();
- if (initializeComponents) {
+ if (mInitializeComponents) {
mSysUIComponent.init();
}
@@ -160,6 +161,9 @@ public class SystemUIFactory {
.build();
}
+ protected boolean shouldInitializeComponents() {
+ return mInitializeComponents;
+ }
public GlobalRootComponent getRootComponent() {
return mRootComponent;
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
index 5532a0427e79..d6f0b59accb1 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
@@ -32,8 +32,8 @@ import android.view.View;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
/**
* Visually discloses that contextual data was provided to an assistant.
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistOrbContainer.java b/packages/SystemUI/src/com/android/systemui/assist/AssistOrbContainer.java
index fe48c26c413c..95b9e81a0b14 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistOrbContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistOrbContainer.java
@@ -22,8 +22,8 @@ import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
public class AssistOrbContainer extends FrameLayout {
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistOrbView.java b/packages/SystemUI/src/com/android/systemui/assist/AssistOrbView.java
index 1d032e8aba48..16d9c84c8734 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistOrbView.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistOrbView.java
@@ -32,8 +32,8 @@ import android.view.animation.OvershootInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
public class AssistOrbView extends FrameLayout {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 1c0aa06ad8d1..72db6cd5cc09 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -48,8 +48,8 @@ import android.widget.ScrollView;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import java.lang.annotation.Retention;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
index b44ff294b792..0fb12953bd54 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
@@ -45,8 +45,8 @@ import androidx.annotation.StringRes;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.VerifyCredentialResponse;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/HbmTypes.java b/packages/SystemUI/src/com/android/systemui/biometrics/HbmTypes.java
index 96ee0f7be919..f798005daabb 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/HbmTypes.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/HbmTypes.java
@@ -17,6 +17,7 @@
package com.android.systemui.biometrics;
import android.annotation.IntDef;
+import android.hardware.fingerprint.IUdfpsHbmListener;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -26,10 +27,10 @@ import java.lang.annotation.RetentionPolicy;
*/
public final class HbmTypes {
/** HBM that applies to the whole screen. */
- public static final int GLOBAL_HBM = 0;
+ public static final int GLOBAL_HBM = IUdfpsHbmListener.GLOBAL_HBM;
/** HBM that only applies to a portion of the screen. */
- public static final int LOCAL_HBM = 1;
+ public static final int LOCAL_HBM = IUdfpsHbmListener.LOCAL_HBM;
@Retention(RetentionPolicy.SOURCE)
@IntDef({GLOBAL_HBM, LOCAL_HBM})
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardDrawable.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardDrawable.java
index 71ed3f8c9b0a..6f7e6c33d855 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardDrawable.java
@@ -28,8 +28,8 @@ import androidx.annotation.NonNull;
import com.android.internal.graphics.ColorUtils;
import com.android.settingslib.Utils;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.doze.DozeReceiver;
/**
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
index fc906f2137f2..565e65fbbc92 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
@@ -30,8 +30,8 @@ import android.widget.ImageView;
import androidx.annotation.Nullable;
import com.android.settingslib.Utils;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.StatusBarState;
/**
diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
index fb7fabbe88e3..1e86cf1d0171 100644
--- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
+++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
@@ -120,10 +120,7 @@ public class WirelessChargingAnimation {
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
params.setFitInsetsTypes(0 /* ignore all system bar insets */);
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
- | WindowManager.LayoutParams.FLAG_DIM_BEHIND;
-
- params.dimAmount = .3f;
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
if (looper == null) {
// Use Looper.myLooper() if looper is not specified.
diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java
index 5cc8299acb94..38ffec115fba 100644
--- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java
@@ -21,18 +21,18 @@ import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.PointF;
-import android.graphics.drawable.Animatable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
+import android.view.View;
import android.view.animation.PathInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.settingslib.Utils;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.charging.ChargingRippleView;
import java.text.NumberFormat;
@@ -78,10 +78,6 @@ public class WirelessChargingLayout extends FrameLayout {
inflate(new ContextThemeWrapper(context, style), R.layout.wireless_charging_layout, this);
- // where the circle animation occurs:
- final ImageView chargingView = findViewById(R.id.wireless_charging_view);
- final Animatable chargingAnimation = (Animatable) chargingView.getDrawable();
-
// amount of battery:
final TextView percentage = findViewById(R.id.wireless_charging_percentage);
@@ -126,9 +122,20 @@ public class WirelessChargingLayout extends FrameLayout {
animatorSet.playTogether(textSizeAnimator, textOpacityAnimator, textFadeAnimator);
mRippleView = findViewById(R.id.wireless_charging_ripple);
+ OnAttachStateChangeListener listener = new OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View view) {
+ mRippleView.setDuration(RIPPLE_ANIMATION_DURATION);
+ mRippleView.startRipple();
+ mRippleView.removeOnAttachStateChangeListener(this);
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View view) {}
+ };
+ mRippleView.addOnAttachStateChangeListener(listener);
if (!showTransmittingBatteryLevel) {
- chargingAnimation.start();
animatorSet.start();
return;
}
@@ -197,7 +204,6 @@ public class WirelessChargingLayout extends FrameLayout {
AnimatorSet animatorSetIcon = new AnimatorSet();
animatorSetIcon.playTogether(textOpacityAnimatorIcon, textFadeAnimatorIcon);
- chargingAnimation.start();
animatorSet.start();
animatorSetTransmitting.start();
animatorSetIcon.start();
@@ -213,8 +219,6 @@ public class WirelessChargingLayout extends FrameLayout {
android.R.attr.colorAccent).getDefaultColor());
mRippleView.setOrigin(new PointF(width / 2, height / 2));
mRippleView.setRadius(Math.max(width, height) * 0.5f);
- mRippleView.setDuration(RIPPLE_ANIMATION_DURATION);
- mRippleView.startRipple();
}
super.onLayout(changed, left, top, right, bottom);
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
index aaea9ce98359..88748f9eaac4 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
@@ -24,10 +24,12 @@ import android.view.MotionEvent;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.sensors.ProximitySensor;
import com.android.systemui.util.sensors.ThresholdSensor;
import com.android.systemui.util.time.SystemClock;
@@ -50,6 +52,7 @@ class FalsingCollectorImpl implements FalsingCollector {
private final ProximitySensor mProximitySensor;
private final StatusBarStateController mStatusBarStateController;
private final KeyguardStateController mKeyguardStateController;
+ private final DelayableExecutor mMainExecutor;
private final SystemClock mSystemClock;
private int mState;
@@ -89,7 +92,8 @@ class FalsingCollectorImpl implements FalsingCollector {
FalsingCollectorImpl(FalsingDataProvider falsingDataProvider, FalsingManager falsingManager,
KeyguardUpdateMonitor keyguardUpdateMonitor, HistoryTracker historyTracker,
ProximitySensor proximitySensor, StatusBarStateController statusBarStateController,
- KeyguardStateController keyguardStateController, SystemClock systemClock) {
+ KeyguardStateController keyguardStateController,
+ @Main DelayableExecutor mainExecutor, SystemClock systemClock) {
mFalsingDataProvider = falsingDataProvider;
mFalsingManager = falsingManager;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -97,6 +101,7 @@ class FalsingCollectorImpl implements FalsingCollector {
mProximitySensor = proximitySensor;
mStatusBarStateController = statusBarStateController;
mKeyguardStateController = keyguardStateController;
+ mMainExecutor = mainExecutor;
mSystemClock = systemClock;
@@ -276,7 +281,7 @@ class FalsingCollectorImpl implements FalsingCollector {
@Override
public void onMotionEventComplete() {
- mFalsingDataProvider.onMotionEventComplete();
+ mMainExecutor.executeDelayed(mFalsingDataProvider::onMotionEventComplete , 50);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt
index 1ea1d97cace5..4aa597ef3d28 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt
@@ -22,21 +22,17 @@ import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.annotation.IdRes
import android.content.Intent
-
import android.transition.Transition
import android.transition.TransitionValues
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.view.Window
-
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
-
-import com.android.systemui.Interpolators
import com.android.systemui.R
-
+import com.android.systemui.animation.Interpolators
import com.android.systemui.controls.ui.ControlsUiController
object ControlsAnimations {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
index 3e0289022162..43607dd7b75d 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
@@ -47,8 +47,8 @@ import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import com.android.internal.graphics.ColorUtils
-import com.android.systemui.Interpolators
import com.android.systemui.R
+import com.android.systemui.animation.Interpolators
import com.android.systemui.controls.ControlsMetricsLogger
import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.util.concurrency.DelayableExecutor
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
index a3a937acec76..fa36eee7c644 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
@@ -37,8 +37,8 @@ import android.view.View
import android.view.ViewGroup
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
-import com.android.systemui.Interpolators
import com.android.systemui.R
+import com.android.systemui.animation.Interpolators
import com.android.systemui.controls.ui.ControlViewHolder.Companion.MAX_LEVEL
import com.android.systemui.controls.ui.ControlViewHolder.Companion.MIN_LEVEL
import java.util.IllegalFormatException
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index ab1de9528586..a83b13c50671 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -61,7 +61,7 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.view.RotationPolicy;
import com.android.internal.widget.LockPatternUtils;
-import com.android.systemui.Interpolators;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.dagger.qualifiers.Background;
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index 47ae145590b5..e44e305b6120 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -107,9 +107,9 @@ import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.EmergencyAffordanceManager;
import com.android.internal.util.ScreenshotHelper;
import com.android.internal.widget.LockPatternUtils;
-import com.android.systemui.Interpolators;
import com.android.systemui.MultiListLayout;
import com.android.systemui.MultiListLayout.MultiListAdapter;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.dagger.qualifiers.Background;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
index 127128dda112..bec4ce6ba658 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
@@ -19,6 +19,7 @@ package com.android.systemui.keyguard;
import android.annotation.Nullable;
import android.content.res.ColorStateList;
import android.graphics.Color;
+import android.text.TextUtils;
import android.view.View;
import androidx.annotation.IntDef;
@@ -69,8 +70,7 @@ public class KeyguardIndicationRotateTextViewController extends
public KeyguardIndicationRotateTextViewController(
KeyguardIndicationTextView view,
@Main DelayableExecutor executor,
- StatusBarStateController statusBarStateController,
- int lockScreenMode
+ StatusBarStateController statusBarStateController
) {
super(view);
mMaxAlpha = view.getAlpha();
@@ -78,7 +78,6 @@ public class KeyguardIndicationRotateTextViewController extends
mInitialTextColorState = mView != null
? mView.getTextColors() : ColorStateList.valueOf(Color.WHITE);
mStatusBarStateController = statusBarStateController;
- mView.setLockScreenMode(lockScreenMode);
init();
}
@@ -102,7 +101,7 @@ public class KeyguardIndicationRotateTextViewController extends
* the IndicationQueue comes around.
*/
public void updateIndication(@IndicationType int type, KeyguardIndication newIndication,
- boolean showImmediately) {
+ boolean updateImmediately) {
if (type == INDICATION_TYPE_NOW_PLAYING
|| type == INDICATION_TYPE_REVERSE_CHARGING) {
// temporarily don't show here, instead use AmbientContainer b/181049781
@@ -125,7 +124,7 @@ public class KeyguardIndicationRotateTextViewController extends
return;
}
- final boolean showNow = showImmediately
+ final boolean showNow = updateImmediately
|| mCurrIndicationType == INDICATION_TYPE_NONE
|| mCurrIndicationType == type;
if (hasNewIndication) {
@@ -139,7 +138,7 @@ public class KeyguardIndicationRotateTextViewController extends
if (mCurrIndicationType == type
&& !hasNewIndication
- && showImmediately) {
+ && updateImmediately) {
if (mShowNextIndicationRunnable != null) {
mShowNextIndicationRunnable.runImmediately();
} else {
@@ -154,6 +153,10 @@ public class KeyguardIndicationRotateTextViewController extends
* If the current indication is of this type, immediately stops showing the message.
*/
public void hideIndication(@IndicationType int type) {
+ if (!mIndicationMessages.containsKey(type)
+ || TextUtils.isEmpty(mIndicationMessages.get(type).getMessage())) {
+ return;
+ }
updateIndication(type, null, true);
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index b227c7dd131c..70459df3dafb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -94,8 +94,8 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.KeyguardViewController;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.Dumpable;
-import com.android.systemui.Interpolators;
import com.android.systemui.SystemUI;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.dagger.qualifiers.UiBackground;
diff --git a/packages/SystemUI/src/com/android/systemui/media/IlluminationDrawable.kt b/packages/SystemUI/src/com/android/systemui/media/IlluminationDrawable.kt
index bc451137d7f5..121ddd46976d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/IlluminationDrawable.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/IlluminationDrawable.kt
@@ -36,8 +36,8 @@ import android.view.View
import androidx.annotation.Keep
import com.android.internal.graphics.ColorUtils
import com.android.internal.graphics.ColorUtils.blendARGB
-import com.android.systemui.Interpolators
import com.android.systemui.R
+import com.android.systemui.animation.Interpolators
import org.xmlpull.v1.XmlPullParser
private const val BACKGROUND_ANIM_DURATION = 370L
diff --git a/packages/SystemUI/src/com/android/systemui/media/LightSourceDrawable.kt b/packages/SystemUI/src/com/android/systemui/media/LightSourceDrawable.kt
index e6035f35fe71..711cb361f437 100644
--- a/packages/SystemUI/src/com/android/systemui/media/LightSourceDrawable.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/LightSourceDrawable.kt
@@ -36,8 +36,8 @@ import android.util.AttributeSet
import android.util.MathUtils.lerp
import androidx.annotation.Keep
import com.android.internal.graphics.ColorUtils
-import com.android.systemui.Interpolators
import com.android.systemui.R
+import com.android.systemui.animation.Interpolators
import org.xmlpull.v1.XmlPullParser
private const val RIPPLE_ANIM_DURATION = 800L
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index a3ff3753cbf9..2ecd40578d68 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -1,6 +1,7 @@
package com.android.systemui.media
import android.animation.ArgbEvaluator
+import android.app.smartspace.SmartspaceTarget
import android.content.Context
import android.content.Intent
import android.content.res.ColorStateList
@@ -201,9 +202,19 @@ class MediaCarouselController @Inject constructor(
}
}
+ override fun onSmartspaceMediaDataLoaded(key: String, data: SmartspaceTarget) {
+ Log.d(TAG, "My Smartspace media update is here")
+ addSmartspaceMediaRecommendations(key, data)
+ }
+
override fun onMediaDataRemoved(key: String) {
removePlayer(key)
}
+
+ override fun onSmartspaceMediaDataRemoved(key: String) {
+ Log.d(TAG, "My Smartspace media removal request is received")
+ removePlayer(key)
+ }
})
mediaFrame.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
// The pageIndicator is not laid out yet when we get the current state update,
@@ -246,8 +257,10 @@ class MediaCarouselController @Inject constructor(
private fun reorderAllPlayers() {
mediaContent.removeAllViews()
for (mediaPlayer in MediaPlayerData.players()) {
- mediaPlayer.view?.let {
+ mediaPlayer.playerViewHolder?.let {
mediaContent.addView(it.player)
+ } ?: mediaPlayer.recommendationViewHolder?.let {
+ mediaContent.addView(it.recommendations)
}
}
mediaCarouselScrollHandler.onPlayersChanged()
@@ -262,18 +275,19 @@ class MediaCarouselController @Inject constructor(
val existingPlayer = MediaPlayerData.getMediaPlayer(key, oldKey)
if (existingPlayer == null) {
var newPlayer = mediaControlPanelFactory.get()
- newPlayer.attach(PlayerViewHolder.create(LayoutInflater.from(context), mediaContent))
+ newPlayer.attachPlayer(
+ PlayerViewHolder.create(LayoutInflater.from(context), mediaContent))
newPlayer.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT)
- newPlayer.view?.player?.setLayoutParams(lp)
- newPlayer.bind(dataCopy, key)
+ newPlayer.playerViewHolder?.player?.setLayoutParams(lp)
+ newPlayer.bindPlayer(dataCopy, key)
newPlayer.setListening(currentlyExpanded)
MediaPlayerData.addMediaPlayer(key, dataCopy, newPlayer)
updatePlayerToState(newPlayer, noAnimation = true)
reorderAllPlayers()
} else {
- existingPlayer.bind(dataCopy, key)
+ existingPlayer.bindPlayer(dataCopy, key)
MediaPlayerData.addMediaPlayer(key, dataCopy, existingPlayer)
if (visualStabilityManager.isReorderingAllowed) {
reorderAllPlayers()
@@ -291,11 +305,43 @@ class MediaCarouselController @Inject constructor(
}
}
- private fun removePlayer(key: String, dismissMediaData: Boolean = true) {
+ private fun addSmartspaceMediaRecommendations(key: String, data: SmartspaceTarget) {
+ Log.d(TAG, "Updating smartspace target in carousel")
+ if (MediaPlayerData.getMediaPlayer(key, null) != null) {
+ Log.w(TAG, "Skip adding smartspace target in carousel")
+ return
+ }
+
+ var newRecs = mediaControlPanelFactory.get()
+ newRecs.attachRecommendation(
+ RecommendationViewHolder.create(LayoutInflater.from(context), mediaContent))
+ newRecs.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
+ val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT)
+ newRecs.recommendationViewHolder?.recommendations?.setLayoutParams(lp)
+ newRecs.bindRecommendation(data, bgColor, { v -> removePlayer(key) })
+ MediaPlayerData.addMediaPlayer(key, newRecs)
+ updatePlayerToState(newRecs, noAnimation = true)
+ reorderAllPlayers()
+ updatePageIndicator()
+ mediaCarousel.requiresRemeasuring = true
+ // Check postcondition: mediaContent should have the same number of children as there are
+ // elements in mediaPlayers.
+ if (MediaPlayerData.players().size != mediaContent.childCount) {
+ Log.wtf(TAG, "Size of players list and number of views in carousel are out of sync")
+ }
+ }
+
+ private fun removePlayer(
+ key: String,
+ dismissMediaData: Boolean = true,
+ dismissRecommendation: Boolean = true
+ ) {
val removed = MediaPlayerData.removeMediaPlayer(key)
removed?.apply {
mediaCarouselScrollHandler.onPrePlayerRemoved(removed)
- mediaContent.removeView(removed.view?.player)
+ mediaContent.removeView(removed.playerViewHolder?.player)
+ mediaContent.removeView(removed.recommendationViewHolder?.recommendations)
removed.onDestroy()
mediaCarouselScrollHandler.onPlayersChanged()
updatePageIndicator()
@@ -304,6 +350,10 @@ class MediaCarouselController @Inject constructor(
// Inform the media manager of a potentially late dismissal
mediaManager.dismissMediaData(key, 0L)
}
+ if (dismissRecommendation) {
+ // Inform the media manager of a potentially late dismissal
+ mediaManager.dismissSmartspaceRecommendation()
+ }
}
}
@@ -525,23 +575,37 @@ class MediaCarouselController @Inject constructor(
@VisibleForTesting
internal object MediaPlayerData {
+ private val EMPTY = MediaData(-1, false, 0, null, null, null, null, null,
+ emptyList(), emptyList(), "INVALID", null, null, null, true, null)
+
private data class MediaSortKey(
+ // Is Smartspace media recommendation. When the Smartspace media is present, it should
+ // always be the first card in carousel.
+ val isSsMediaRec: Boolean,
val data: MediaData,
val updateTime: Long = 0
)
private val comparator =
- compareByDescending<MediaSortKey> { it.data.isPlaying }
- .thenByDescending { it.data.isLocalSession }
- .thenByDescending { !it.data.resumption }
- .thenByDescending { it.updateTime }
+ compareByDescending<MediaSortKey> { it.isSsMediaRec }
+ .thenByDescending { it.data.isPlaying }
+ .thenByDescending { it.data.isLocalSession }
+ .thenByDescending { !it.data.resumption }
+ .thenByDescending { it.updateTime }
private val mediaPlayers = TreeMap<MediaSortKey, MediaControlPanel>(comparator)
private val mediaData: MutableMap<String, MediaSortKey> = mutableMapOf()
fun addMediaPlayer(key: String, data: MediaData, player: MediaControlPanel) {
removeMediaPlayer(key)
- val sortKey = MediaSortKey(data, System.currentTimeMillis())
+ val sortKey = MediaSortKey(isSsMediaRec = false, data, System.currentTimeMillis())
+ mediaData.put(key, sortKey)
+ mediaPlayers.put(sortKey, player)
+ }
+
+ fun addMediaPlayer(key: String, player: MediaControlPanel) {
+ removeMediaPlayer(key)
+ val sortKey = MediaSortKey(isSsMediaRec = true, EMPTY, System.currentTimeMillis())
mediaData.put(key, sortKey)
mediaPlayers.put(sortKey, player)
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
index bb6fbfab4c90..f0b78dde0ebd 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
@@ -510,7 +510,7 @@ class MediaCarouselScrollHandler(
* where it was and update our scroll position.
*/
fun onPrePlayerRemoved(removed: MediaControlPanel) {
- val removedIndex = mediaContent.indexOfChild(removed.view?.player)
+ val removedIndex = mediaContent.indexOfChild(removed.playerViewHolder?.player)
// If the removed index is less than the activeMediaIndex, then we need to decrement it.
// RTL has no effect on this, because indices are always relative (start-to-end).
// Update the index 'manually' since we won't always get a call to onMediaScrollingChanged
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 4fd8fe7b921b..495461e5b860 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -16,12 +16,14 @@
package com.android.systemui.media;
-import static android.app.Notification.safeCharSequence;
import static android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS;
import android.app.PendingIntent;
+import android.app.smartspace.SmartspaceAction;
+import android.app.smartspace.SmartspaceTarget;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.graphics.Outline;
import android.graphics.Rect;
@@ -30,6 +32,7 @@ import android.graphics.drawable.Icon;
import android.media.session.MediaController;
import android.media.session.MediaSession;
import android.media.session.PlaybackState;
+import android.os.Bundle;
import android.os.SystemProperties;
import android.util.Log;
import android.view.View;
@@ -46,11 +49,11 @@ import androidx.constraintlayout.widget.ConstraintSet;
import com.android.settingslib.Utils;
import com.android.settingslib.widget.AdaptiveIcon;
import com.android.systemui.R;
+import com.android.systemui.animation.ActivityLaunchAnimator;
+import com.android.systemui.animation.GhostedViewLaunchAnimatorController;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.animation.ActivityLaunchAnimator;
-import com.android.systemui.plugins.animation.GhostedViewLaunchAnimatorController;
import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
import com.android.systemui.util.animation.TransitionLayout;
@@ -67,6 +70,9 @@ import dagger.Lazy;
public class MediaControlPanel {
private static final String TAG = "MediaControlPanel";
private static final float DISABLED_ALPHA = 0.38f;
+ private static final String EXTRAS_MEDIA_SOURCE_LOGO = "media_source_logo";
+ private static final String EXTRAS_MEDIA_SOURCE_PACKAGE_NAME = "package_name";
+ private static final int MEDIA_RECOMMENDATION_MAX_NUM = 4;
private final boolean mShowAppName = SystemProperties.getBoolean(
"persist.sysui.qs_media_show_app_name", false);
@@ -90,7 +96,8 @@ public class MediaControlPanel {
private final ActivityStarter mActivityStarter;
private Context mContext;
- private PlayerViewHolder mViewHolder;
+ private PlayerViewHolder mPlayerViewHolder;
+ private RecommendationViewHolder mRecommendationViewHolder;
private String mKey;
private MediaViewController mMediaViewController;
private MediaSession.Token mToken;
@@ -149,13 +156,22 @@ public class MediaControlPanel {
}
/**
- * Get the view holder used to display media controls
+ * Get the player view holder used to display media controls.
*
- * @return the view holder
+ * @return the player view holder
*/
@Nullable
- public PlayerViewHolder getView() {
- return mViewHolder;
+ public PlayerViewHolder getPlayerViewHolder() {
+ return mPlayerViewHolder;
+ }
+
+ /**
+ * Get the recommendation view holder used to display Smartspace media recs.
+ * @return the recommendation view holder
+ */
+ @Nullable
+ public RecommendationViewHolder getRecommendationViewHolder() {
+ return mRecommendationViewHolder;
}
/**
@@ -189,9 +205,9 @@ public class MediaControlPanel {
return mContext;
}
- /** Attaches the player to the view holder. */
- public void attach(PlayerViewHolder vh) {
- mViewHolder = vh;
+ /** Attaches the player to the player view holder. */
+ public void attachPlayer(PlayerViewHolder vh) {
+ mPlayerViewHolder = vh;
TransitionLayout player = vh.getPlayer();
ImageView albumView = vh.getAlbumView();
@@ -201,9 +217,9 @@ public class MediaControlPanel {
mSeekBarObserver = new SeekBarObserver(vh);
mSeekBarViewModel.getProgress().observeForever(mSeekBarObserver);
mSeekBarViewModel.attachTouchHandlers(vh.getSeekBar());
- mMediaViewController.attach(player);
+ mMediaViewController.attach(player, MediaViewController.TYPE.PLAYER);
- mViewHolder.getPlayer().setOnLongClickListener(v -> {
+ mPlayerViewHolder.getPlayer().setOnLongClickListener(v -> {
if (!mMediaViewController.isGutsVisible()) {
mMediaViewController.openGuts();
return true;
@@ -211,19 +227,25 @@ public class MediaControlPanel {
return false;
}
});
- mViewHolder.getCancel().setOnClickListener(v -> {
+ mPlayerViewHolder.getCancel().setOnClickListener(v -> {
closeGuts();
});
- mViewHolder.getSettings().setOnClickListener(v -> {
+ mPlayerViewHolder.getSettings().setOnClickListener(v -> {
mActivityStarter.startActivity(SETTINGS_INTENT, true /* dismissShade */);
});
}
- /**
- * Bind this view based on the data given
- */
- public void bind(@NonNull MediaData data, String key) {
- if (mViewHolder == null) {
+ /** Attaches the recommendations to the recommendation view holder. */
+ public void attachRecommendation(RecommendationViewHolder vh) {
+ mRecommendationViewHolder = vh;
+ TransitionLayout recommendations = vh.getRecommendations();
+
+ mMediaViewController.attach(recommendations, MediaViewController.TYPE.RECOMMENDATION);
+ }
+
+ /** Bind this player view based on the data given. */
+ public void bindPlayer(@NonNull MediaData data, String key) {
+ if (mPlayerViewHolder == null) {
return;
}
mKey = key;
@@ -242,20 +264,20 @@ public class MediaControlPanel {
ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
- mViewHolder.getPlayer().setBackgroundTintList(
+ mPlayerViewHolder.getPlayer().setBackgroundTintList(
ColorStateList.valueOf(mBackgroundColor));
// Click action
PendingIntent clickIntent = data.getClickIntent();
if (clickIntent != null) {
- mViewHolder.getPlayer().setOnClickListener(v -> {
+ mPlayerViewHolder.getPlayer().setOnClickListener(v -> {
if (mMediaViewController.isGutsVisible()) return;
mActivityStarter.postStartActivityDismissingKeyguard(clickIntent,
- buildLaunchAnimatorController(mViewHolder.getPlayer()));
+ buildLaunchAnimatorController(mPlayerViewHolder.getPlayer()));
});
}
- ImageView albumView = mViewHolder.getAlbumView();
+ ImageView albumView = mPlayerViewHolder.getAlbumView();
boolean hasArtwork = data.getArtwork() != null;
if (hasArtwork) {
Drawable artwork = scaleDrawable(data.getArtwork());
@@ -265,7 +287,7 @@ public class MediaControlPanel {
setVisibleAndAlpha(expandedSet, R.id.album_art, hasArtwork);
// App icon
- ImageView appIcon = mViewHolder.getAppIcon();
+ ImageView appIcon = mPlayerViewHolder.getAppIcon();
if (data.getAppIcon() != null) {
appIcon.setImageIcon(data.getAppIcon());
} else {
@@ -273,52 +295,53 @@ public class MediaControlPanel {
}
// Song name
- TextView titleText = mViewHolder.getTitleText();
- titleText.setText(safeCharSequence(data.getSong()));
+
+ TextView titleText = mPlayerViewHolder.getTitleText();
+ titleText.setText(data.getSong());
// App title
- TextView appName = mViewHolder.getAppName();
+ TextView appName = mPlayerViewHolder.getAppName();
appName.setText(data.getApp());
appName.setVisibility(mShowAppName ? View.VISIBLE : View.GONE);
setVisibleAndAlpha(collapsedSet, R.id.app_name, mShowAppName);
setVisibleAndAlpha(expandedSet, R.id.app_name, mShowAppName);
// Artist name
- TextView artistText = mViewHolder.getArtistText();
- artistText.setText(safeCharSequence(data.getArtist()));
+ TextView artistText = mPlayerViewHolder.getArtistText();
+ artistText.setText(data.getArtist());
// Transfer chip
- mViewHolder.getSeamless().setVisibility(View.VISIBLE);
+ mPlayerViewHolder.getSeamless().setVisibility(View.VISIBLE);
setVisibleAndAlpha(collapsedSet, R.id.media_seamless, true /*visible */);
setVisibleAndAlpha(expandedSet, R.id.media_seamless, true /*visible */);
- mViewHolder.getSeamless().setOnClickListener(v -> {
+ mPlayerViewHolder.getSeamless().setOnClickListener(v -> {
mMediaOutputDialogFactory.create(data.getPackageName(), true);
});
- TextView mDeviceName = mViewHolder.getSeamlessText();
+ TextView mDeviceName = mPlayerViewHolder.getSeamlessText();
mDeviceName.setVisibility(mShowDeviceName ? View.VISIBLE : View.GONE);
setVisibleAndAlpha(collapsedSet, R.id.media_seamless_text, mShowDeviceName);
setVisibleAndAlpha(expandedSet, R.id.media_seamless_text, mShowDeviceName);
- ImageView iconView = mViewHolder.getSeamlessIcon();
- TextView deviceName = mViewHolder.getSeamlessText();
+ ImageView iconView = mPlayerViewHolder.getSeamlessIcon();
+ TextView deviceName = mPlayerViewHolder.getSeamlessText();
final MediaDeviceData device = data.getDevice();
- final int seamlessId = mViewHolder.getSeamless().getId();
- final int seamlessFallbackId = mViewHolder.getSeamlessFallback().getId();
+ final int seamlessId = mPlayerViewHolder.getSeamless().getId();
+ final int seamlessFallbackId = mPlayerViewHolder.getSeamlessFallback().getId();
final boolean showFallback = device != null && !device.getEnabled();
final int seamlessFallbackVisibility = showFallback ? View.VISIBLE : View.GONE;
- mViewHolder.getSeamlessFallback().setVisibility(seamlessFallbackVisibility);
+ mPlayerViewHolder.getSeamlessFallback().setVisibility(seamlessFallbackVisibility);
expandedSet.setVisibility(seamlessFallbackId, seamlessFallbackVisibility);
collapsedSet.setVisibility(seamlessFallbackId, seamlessFallbackVisibility);
final int seamlessVisibility = showFallback ? View.GONE : View.VISIBLE;
- mViewHolder.getSeamless().setVisibility(seamlessVisibility);
+ mPlayerViewHolder.getSeamless().setVisibility(seamlessVisibility);
expandedSet.setVisibility(seamlessId, seamlessVisibility);
collapsedSet.setVisibility(seamlessId, seamlessVisibility);
final float seamlessAlpha = data.getResumption() ? DISABLED_ALPHA : 1.0f;
expandedSet.setAlpha(seamlessId, seamlessAlpha);
collapsedSet.setAlpha(seamlessId, seamlessAlpha);
// Disable clicking on output switcher for resumption controls.
- mViewHolder.getSeamless().setEnabled(!data.getResumption());
+ mPlayerViewHolder.getSeamless().setEnabled(!data.getResumption());
if (showFallback) {
iconView.setImageDrawable(null);
deviceName.setText(null);
@@ -346,7 +369,7 @@ public class MediaControlPanel {
List<MediaAction> actionIcons = data.getActions();
for (; i < actionIcons.size() && i < ACTION_IDS.length; i++) {
int actionId = ACTION_IDS[i];
- final ImageButton button = mViewHolder.getAction(actionId);
+ final ImageButton button = mPlayerViewHolder.getAction(actionId);
MediaAction mediaAction = actionIcons.get(i);
button.setImageIcon(mediaAction.getIcon());
button.setContentDescription(mediaAction.getContentDescription());
@@ -377,14 +400,14 @@ public class MediaControlPanel {
// Guts label
boolean isDismissible = data.isClearable();
- mViewHolder.getSettingsText().setText(isDismissible
+ mPlayerViewHolder.getSettingsText().setText(isDismissible
? R.string.controls_media_close_session
: R.string.controls_media_active_session);
// Dismiss
- mViewHolder.getDismissLabel().setAlpha(isDismissible ? 1 : DISABLED_ALPHA);
- mViewHolder.getDismiss().setEnabled(isDismissible);
- mViewHolder.getDismiss().setOnClickListener(v -> {
+ mPlayerViewHolder.getDismissLabel().setAlpha(isDismissible ? 1 : DISABLED_ALPHA);
+ mPlayerViewHolder.getDismiss().setEnabled(isDismissible);
+ mPlayerViewHolder.getDismiss().setOnClickListener(v -> {
if (mKey != null) {
closeGuts();
mKeyguardDismissUtil.executeWhenUnlocked(() -> {
@@ -436,6 +459,78 @@ public class MediaControlPanel {
};
}
+ /** Bind this recommendation view based on the data given. */
+ public void bindRecommendation(
+ @NonNull SmartspaceTarget target,
+ @NonNull int backgroundColor,
+ @Nullable View.OnClickListener callback) {
+ if (mRecommendationViewHolder == null) {
+ return;
+ }
+
+ mRecommendationViewHolder.getRecommendations()
+ .setBackgroundTintList(ColorStateList.valueOf(backgroundColor));
+ mBackgroundColor = backgroundColor;
+
+ List<SmartspaceAction> mediaRecommendationList = target.getIconGrid();
+ if (mediaRecommendationList == null || mediaRecommendationList.isEmpty()) {
+ Log.w(TAG, "Empty media recommendations");
+ return;
+ }
+
+ List<ImageView> mediaCoverItems = mRecommendationViewHolder.getMediaCoverItems();
+ List<ImageView> mediaLogoItems = mRecommendationViewHolder.getMediaLogoItems();
+ List<Integer> mediaCoverItemsResIds = mRecommendationViewHolder.getMediaCoverItemsResIds();
+ List<Integer> mediaLogoItemsResIds = mRecommendationViewHolder.getMediaLogoItemsResIds();
+ ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
+ ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
+ int mediaRecommendationNum = Math.min(mediaRecommendationList.size(),
+ MEDIA_RECOMMENDATION_MAX_NUM);
+ for (int i = 0; i < mediaRecommendationNum; i++) {
+ SmartspaceAction recommendation = mediaRecommendationList.get(i);
+ if (recommendation.getIcon() == null) {
+ Log.w(TAG, "No media cover is provided. Skipping this item...");
+ continue;
+ }
+
+ // Get media source app's logo.
+ Bundle extras = recommendation.getExtras();
+ Drawable icon = null;
+ if (extras != null && extras.getString(EXTRAS_MEDIA_SOURCE_PACKAGE_NAME) != null) {
+ // Get the logo from app's package name when applicable.
+ String packageName = extras.getString(EXTRAS_MEDIA_SOURCE_PACKAGE_NAME);
+ try {
+ icon = mContext.getPackageManager().getApplicationIcon(
+ packageName);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "No media source icon can be fetched via package name", e);
+ }
+ } else {
+ Log.w(TAG, "No media source icon is provided. Skipping this item...");
+ continue;
+ }
+
+ // Set up media source app's logo.
+ ImageView mediaSourceLogoImageView = mediaLogoItems.get(i);
+ mediaSourceLogoImageView.setImageDrawable(icon);
+
+ // Set up media item cover.
+ ImageView mediaCoverImageView = mediaCoverItems.get(i);
+ mediaCoverImageView.setImageIcon(recommendation.getIcon());
+
+ // Set up the click listener if applicable.
+ setSmartspaceOnClickListener(mediaCoverImageView, recommendation, callback);
+
+ setVisibleAndAlpha(expandedSet, mediaCoverItemsResIds.get(i), true);
+ setVisibleAndAlpha(expandedSet, mediaLogoItemsResIds.get(i), true);
+ setVisibleAndAlpha(collapsedSet, mediaCoverItemsResIds.get(i), true);
+ setVisibleAndAlpha(collapsedSet, mediaLogoItemsResIds.get(i), true);
+ }
+
+ mController = null;
+ mMediaViewController.refreshState();
+ }
+
/**
* Close the guts for this player.
*
@@ -515,4 +610,24 @@ public class MediaControlPanel {
set.setVisibility(actionId, visible ? ConstraintSet.VISIBLE : ConstraintSet.GONE);
set.setAlpha(actionId, visible ? 1.0f : 0.0f);
}
+
+ private void setSmartspaceOnClickListener(
+ @NonNull View view,
+ @NonNull SmartspaceAction action,
+ @Nullable View.OnClickListener callback) {
+ if (view == null || action == null || action.getIntent() == null) {
+ Log.e(TAG, "No tap action can be set up");
+ return;
+ }
+
+ view.setOnClickListener(v -> {
+ mActivityStarter.postStartActivityDismissingKeyguard(
+ action.getIntent(),
+ 0 /* delay */,
+ buildLaunchAnimatorController(mRecommendationViewHolder.getRecommendations()));
+ if (callback != null) {
+ callback.onClick(v);
+ }
+ });
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt
index aa3699e9a22b..2c094b885032 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.media
+import android.app.smartspace.SmartspaceTarget
import javax.inject.Inject
/**
@@ -37,10 +38,18 @@ class MediaDataCombineLatest @Inject constructor() : MediaDataManager.Listener,
}
}
+ override fun onSmartspaceMediaDataLoaded(key: String, data: SmartspaceTarget) {
+ listeners.toSet().forEach { it.onSmartspaceMediaDataLoaded(key, data) }
+ }
+
override fun onMediaDataRemoved(key: String) {
remove(key)
}
+ override fun onSmartspaceMediaDataRemoved(key: String) {
+ listeners.toSet().forEach { it.onSmartspaceMediaDataRemoved(key) }
+ }
+
override fun onMediaDeviceChanged(
key: String,
oldKey: String?,
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
index 1f580a953d09..a274eabed198 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
@@ -16,6 +16,7 @@
package com.android.systemui.media
+import android.app.smartspace.SmartspaceTarget
import android.util.Log
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.broadcast.BroadcastDispatcher
@@ -50,6 +51,7 @@ class MediaDataFilter @Inject constructor(
private val allEntries: LinkedHashMap<String, MediaData> = LinkedHashMap()
// The filtered userEntries, which will be a subset of all userEntries in MediaDataManager
private val userEntries: LinkedHashMap<String, MediaData> = LinkedHashMap()
+ private var hasSmartspace: Boolean = false
init {
userTracker = object : CurrentUserTracker(broadcastDispatcher) {
@@ -82,6 +84,11 @@ class MediaDataFilter @Inject constructor(
}
}
+ override fun onSmartspaceMediaDataLoaded(key: String, data: SmartspaceTarget) {
+ hasSmartspace = true
+ listeners.forEach { it.onSmartspaceMediaDataLoaded(key, data) }
+ }
+
override fun onMediaDataRemoved(key: String) {
allEntries.remove(key)
userEntries.remove(key)?.let {
@@ -92,6 +99,11 @@ class MediaDataFilter @Inject constructor(
}
}
+ override fun onSmartspaceMediaDataRemoved(key: String) {
+ hasSmartspace = false
+ listeners.forEach { it.onSmartspaceMediaDataRemoved(key) }
+ }
+
@VisibleForTesting
internal fun handleUserSwitched(id: Int) {
// If the user changes, remove all current MediaData objects and inform listeners
@@ -127,17 +139,20 @@ class MediaDataFilter @Inject constructor(
mediaKeys.forEach {
mediaDataManager.setTimedOut(it, timedOut = true)
}
+ if (hasSmartspace) {
+ mediaDataManager.dismissSmartspaceRecommendation()
+ }
}
/**
* Are there any media notifications active?
*/
- fun hasActiveMedia() = userEntries.any { it.value.active }
+ fun hasActiveMedia() = userEntries.any { it.value.active } || hasSmartspace
/**
* Are there any media entries we should display?
*/
- fun hasAnyMedia() = userEntries.isNotEmpty()
+ fun hasAnyMedia() = userEntries.isNotEmpty() || hasSmartspace
/**
* Add a listener for filtered [MediaData] changes
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index 41c9daedf2d4..574ce0dffee0 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -18,6 +18,10 @@ package com.android.systemui.media
import android.app.Notification
import android.app.PendingIntent
+import android.app.smartspace.SmartspaceConfig
+import android.app.smartspace.SmartspaceManager
+import android.app.smartspace.SmartspaceSession
+import android.app.smartspace.SmartspaceTarget
import android.content.BroadcastReceiver
import android.content.ContentResolver
import android.content.Context
@@ -33,6 +37,7 @@ import android.media.MediaMetadata
import android.media.session.MediaController
import android.media.session.MediaSession
import android.net.Uri
+import android.os.Parcelable
import android.os.UserHandle
import android.service.notification.StatusBarNotification
import android.text.TextUtils
@@ -45,6 +50,7 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.BcSmartspaceDataPlugin
import com.android.systemui.statusbar.NotificationMediaManager.isPlayingState
import com.android.systemui.statusbar.notification.row.HybridGroupManager
import com.android.systemui.util.Assert
@@ -54,6 +60,7 @@ import java.io.FileDescriptor
import java.io.IOException
import java.io.PrintWriter
import java.util.concurrent.Executor
+import java.util.concurrent.Executors
import javax.inject.Inject
// URI fields to try loading album art from
@@ -99,9 +106,16 @@ class MediaDataManager(
mediaDataCombineLatest: MediaDataCombineLatest,
private val mediaDataFilter: MediaDataFilter,
private val activityStarter: ActivityStarter,
+ private val smartspaceMediaDataProvider: SmartspaceMediaDataProvider,
private var useMediaResumption: Boolean,
private val useQsMediaPlayer: Boolean
-) : Dumpable {
+) : Dumpable, BcSmartspaceDataPlugin.SmartspaceTargetListener {
+
+ companion object {
+ // UI surface label for subscribing Smartspace updates.
+ @JvmField
+ val SMARTSPACE_UI_SURFACE_LABEL = "media_data_manager"
+ }
private val themeText = com.android.settingslib.Utils.getColorAttr(context,
com.android.internal.R.attr.textColorPrimary).defaultColor
@@ -117,6 +131,8 @@ class MediaDataManager(
// TODO(b/159539991#comment5): Move internal listeners to separate package.
private val internalListeners: MutableSet<Listener> = mutableSetOf()
private val mediaEntries: LinkedHashMap<String, MediaData> = LinkedHashMap()
+ // There should ONLY be at most one Smartspace media recommendation.
+ private var smartspaceMediaTarget: SmartspaceTarget? = null
internal var appsBlockedFromResume: MutableSet<String> = Utils.getBlockedMediaApps(context)
set(value) {
// Update list
@@ -128,6 +144,7 @@ class MediaDataManager(
removeAllForPackage(it)
}
}
+ private var smartspaceSession: SmartspaceSession? = null
@Inject
constructor(
@@ -143,11 +160,13 @@ class MediaDataManager(
mediaDeviceManager: MediaDeviceManager,
mediaDataCombineLatest: MediaDataCombineLatest,
mediaDataFilter: MediaDataFilter,
- activityStarter: ActivityStarter
+ activityStarter: ActivityStarter,
+ smartspaceMediaDataProvider: SmartspaceMediaDataProvider
) : this(context, backgroundExecutor, foregroundExecutor, mediaControllerFactory,
broadcastDispatcher, dumpManager, mediaTimeoutListener, mediaResumeListener,
mediaSessionBasedFilter, mediaDeviceManager, mediaDataCombineLatest, mediaDataFilter,
- activityStarter, Utils.useMediaResumption(context), Utils.useQsMediaPlayer(context))
+ activityStarter, smartspaceMediaDataProvider, Utils.useMediaResumption(context),
+ Utils.useQsMediaPlayer(context))
private val appChangeReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
@@ -200,9 +219,31 @@ class MediaDataManager(
}
// BroadcastDispatcher does not allow filters with data schemes
context.registerReceiver(appChangeReceiver, uninstallFilter)
+
+ // Register for Smartspace data updates.
+ smartspaceMediaDataProvider.registerListener(this)
+ val smartspaceManager: SmartspaceManager =
+ context.getSystemService(SmartspaceManager::class.java)
+ smartspaceSession = smartspaceManager.createSmartspaceSession(
+ SmartspaceConfig.Builder(context, SMARTSPACE_UI_SURFACE_LABEL).build())
+ smartspaceSession?.let {
+ it.registerSmartspaceUpdates(
+ // Use a new thread listening to Smartspace updates instead of using the existing
+ // backgroundExecutor. SmartspaceSession has scheduled routine updates which can be
+ // unpredictable on test simulators, using the backgroundExecutor makes it's hard to
+ // test the threads numbers.
+ // Switch to use backgroundExecutor when SmartspaceSession has a good way to be
+ // mocked.
+ Executors.newCachedThreadPool(),
+ SmartspaceSession.Callback { targets ->
+ smartspaceMediaDataProvider.onTargetsAvailable(targets)
+ })
+ }
+ smartspaceSession?.let { it.requestSmartspaceUpdate() }
}
fun destroy() {
+ smartspaceMediaDataProvider.unregisterListener(this)
context.unregisterReceiver(appChangeReceiver)
}
@@ -309,7 +350,7 @@ class MediaDataManager(
private fun addInternalListener(listener: Listener) = internalListeners.add(listener)
/**
- * Notify internal listeners of loaded event.
+ * Notify internal listeners of media loaded event.
*
* External listeners registered with [addListener] will be notified after the event propagates
* through the internal listener pipeline.
@@ -319,7 +360,17 @@ class MediaDataManager(
}
/**
- * Notify internal listeners of removed event.
+ * Notify internal listeners of Smartspace media loaded event.
+ *
+ * External listeners registered with [addListener] will be notified after the event propagates
+ * through the internal listener pipeline.
+ */
+ private fun notifySmartspaceMediaDataLoaded(key: String, info: SmartspaceTarget) {
+ internalListeners.forEach { it.onSmartspaceMediaDataLoaded(key, info) }
+ }
+
+ /**
+ * Notify internal listeners of media removed event.
*
* External listeners registered with [addListener] will be notified after the event propagates
* through the internal listener pipeline.
@@ -329,6 +380,16 @@ class MediaDataManager(
}
/**
+ * Notify internal listeners of Smartspace media removed event.
+ *
+ * External listeners registered with [addListener] will be notified after the event propagates
+ * through the internal listener pipeline.
+ */
+ private fun notifySmartspaceMediaDataRemoved(key: String) {
+ internalListeners.forEach { it.onSmartspaceMediaDataRemoved(key) }
+ }
+
+ /**
* Called whenever the player has been paused or stopped for a while, or swiped from QQS.
* This will make the player not active anymore, hiding it from QQS and Keyguard.
* @see MediaData.active
@@ -363,6 +424,20 @@ class MediaDataManager(
foregroundExecutor.executeDelayed({ removeEntry(key) }, delay)
}
+ /**
+ * Called whenever the recommendation has been expired, or swiped from QQS.
+ * This will make the recommendation view to not be shown anymore during this headphone
+ * connection session.
+ */
+ fun dismissSmartspaceRecommendation() {
+ Log.d(TAG, "Dismissing Smartspace media target")
+ // Do not set smartspaceMediaTarget to null. So the instance is preserved during the entire
+ // headphone connection, and will ONLY be set to null when headphones are disconnected.
+ smartspaceMediaTarget?.let {
+ notifySmartspaceMediaDataRemoved(it.smartspaceTargetId)
+ }
+ }
+
private fun loadMediaDataInBgForResumption(
userId: Int,
desc: MediaDescription,
@@ -601,6 +676,50 @@ class MediaDataManager(
}
}
+ override fun onSmartspaceTargetsUpdated(targets: List<Parcelable>) {
+ Log.d(TAG, "My Smartspace media updates are here")
+ val mediaTargets = targets.filterIsInstance<SmartspaceTarget>()
+ when (mediaTargets.size) {
+ 0 -> {
+ Log.d(TAG, "Empty Smartspace media target")
+ smartspaceMediaTarget?.let {
+ Log.d(TAG, "Setting Smartspace media target to null")
+ notifySmartspaceMediaDataRemoved(it.smartspaceTargetId)
+ }
+ smartspaceMediaTarget = null
+ }
+ 1 -> {
+ // TODO(b/182811956): Reactivate the resumable media sessions whose last active
+ // time is within 3 hours.
+ // TODO(b/182813365): Wire this up with MediaTimeoutListener so the session can be
+ // expired after 30 seconds.
+ val newMediaTarget = mediaTargets.get(0)
+ if (smartspaceMediaTarget != null &&
+ smartspaceMediaTarget!!.smartspaceTargetId ==
+ newMediaTarget.smartspaceTargetId) {
+ // The same Smartspace updates can be received. Only send the first one.
+ Log.d(TAG, "Same Smartspace media update exists. Skip loading data.")
+ } else {
+ smartspaceMediaTarget?.let {
+ notifySmartspaceMediaDataRemoved(it.smartspaceTargetId)
+ }
+ notifySmartspaceMediaDataLoaded(
+ newMediaTarget.smartspaceTargetId, newMediaTarget)
+ smartspaceMediaTarget = newMediaTarget
+ }
+ }
+ else -> {
+ // There should NOT be more than 1 Smartspace media update. When it happens, it
+ // indicates a bad state or an error. Reset the status accordingly.
+ Log.wtf(TAG, "More than 1 Smartspace Media Update. Resetting the status...")
+ smartspaceMediaTarget?.let {
+ notifySmartspaceMediaDataRemoved(it.smartspaceTargetId)
+ }
+ smartspaceMediaTarget = null
+ }
+ }
+ }
+
fun onNotificationRemoved(key: String) {
Assert.isMainThread()
val removed = mediaEntries.remove(key)
@@ -685,10 +804,16 @@ class MediaDataManager(
*/
fun onMediaDataLoaded(key: String, oldKey: String?, data: MediaData) {}
+ /** Called whenever there's new Smartspace media data loaded. */
+ fun onSmartspaceMediaDataLoaded(key: String, data: SmartspaceTarget) {}
+
/**
* Called whenever a previously existing Media notification was removed
*/
fun onMediaDataRemoved(key: String) {}
+
+ /** Called whenever a previously existing Smartspace media data was removed. */
+ fun onSmartspaceMediaDataRemoved(key: String) {}
}
override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index 5475a00ced3c..30bc8c1733bc 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -26,7 +26,7 @@ import android.util.MathUtils
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroupOverlay
-import com.android.systemui.Interpolators
+import com.android.systemui.animation.Interpolators
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.plugins.statusbar.StatusBarStateController
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
index b74ca283f16a..8c12a305992e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
@@ -1,5 +1,6 @@
package com.android.systemui.media
+import android.app.smartspace.SmartspaceTarget
import android.graphics.Rect
import android.util.ArraySet
import android.view.View
@@ -53,9 +54,17 @@ class MediaHost constructor(
updateViewVisibility()
}
+ override fun onSmartspaceMediaDataLoaded(key: String, data: SmartspaceTarget) {
+ updateViewVisibility()
+ }
+
override fun onMediaDataRemoved(key: String) {
updateViewVisibility()
}
+
+ override fun onSmartspaceMediaDataRemoved(key: String) {
+ updateViewVisibility()
+ }
}
fun addVisibilityChangeListener(listener: (Boolean) -> Unit) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt b/packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt
index f695622b943a..d973478625de 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt
@@ -16,6 +16,7 @@
package com.android.systemui.media
+import android.app.smartspace.SmartspaceTarget
import android.content.ComponentName
import android.content.Context
import android.media.session.MediaController
@@ -134,6 +135,12 @@ class MediaSessionBasedFilter @Inject constructor(
}
}
+ override fun onSmartspaceMediaDataLoaded(key: String, data: SmartspaceTarget) {
+ backgroundExecutor.execute {
+ dispatchSmartspaceMediaDataLoaded(key, data)
+ }
+ }
+
override fun onMediaDataRemoved(key: String) {
// Queue on background thread to ensure ordering of loaded and removed events is maintained.
backgroundExecutor.execute {
@@ -142,6 +149,12 @@ class MediaSessionBasedFilter @Inject constructor(
}
}
+ override fun onSmartspaceMediaDataRemoved(key: String) {
+ backgroundExecutor.execute {
+ dispatchSmartspaceMediaDataRemoved(key)
+ }
+ }
+
private fun dispatchMediaDataLoaded(key: String, oldKey: String?, info: MediaData) {
foregroundExecutor.execute {
listeners.toSet().forEach { it.onMediaDataLoaded(key, oldKey, info) }
@@ -154,6 +167,18 @@ class MediaSessionBasedFilter @Inject constructor(
}
}
+ private fun dispatchSmartspaceMediaDataLoaded(key: String, info: SmartspaceTarget) {
+ foregroundExecutor.execute {
+ listeners.toSet().forEach { it.onSmartspaceMediaDataLoaded(key, info) }
+ }
+ }
+
+ private fun dispatchSmartspaceMediaDataRemoved(key: String) {
+ foregroundExecutor.execute {
+ listeners.toSet().forEach { it.onSmartspaceMediaDataRemoved(key) }
+ }
+ }
+
private fun handleControllersChanged(controllers: List<MediaController>) {
packageControllers.clear()
controllers.forEach {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
index 92eeed46388d..7cfe4c4073d2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
@@ -32,11 +32,16 @@ import javax.inject.Inject
* with the view instance and keeping the media view states up to date.
*/
class MediaViewController @Inject constructor(
- context: Context,
+ private val context: Context,
private val configurationController: ConfigurationController,
private val mediaHostStatesManager: MediaHostStatesManager
) {
+ /** Indicating the media view controller is for a player or recommendation. */
+ enum class TYPE {
+ PLAYER, RECOMMENDATION
+ }
+
companion object {
@JvmField
val GUTS_ANIMATION_DURATION = 500L
@@ -53,6 +58,7 @@ class MediaViewController @Inject constructor(
private var animationDuration: Long = 0
private var animateNextStateChange: Boolean = false
private val measurement = MeasurementOutput(0, 0)
+ private var type: TYPE = TYPE.PLAYER
/**
* A map containing all viewStates for all locations of this mediaState
@@ -181,8 +187,6 @@ class MediaViewController @Inject constructor(
private set
init {
- collapsedLayout.load(context, R.xml.media_collapsed)
- expandedLayout.load(context, R.xml.media_expanded)
mediaHostStatesManager.addController(this)
layoutController.sizeChangedListener = { width: Int, height: Int ->
currentWidth = width
@@ -313,7 +317,11 @@ class MediaViewController @Inject constructor(
return result
}
- private fun getKey(state: MediaHostState, guts: Boolean, result: CacheKey): CacheKey {
+ private fun getKey(
+ state: MediaHostState,
+ guts: Boolean,
+ result: CacheKey
+ ): CacheKey {
result.apply {
heightMeasureSpec = state.measurementInput?.heightMeasureSpec ?: 0
widthMeasureSpec = state.measurementInput?.widthMeasureSpec ?: 0
@@ -327,7 +335,8 @@ class MediaViewController @Inject constructor(
* Attach a view to this controller. This may perform measurements if it's not available yet
* and should therefore be done carefully.
*/
- fun attach(transitionLayout: TransitionLayout) {
+ fun attach(transitionLayout: TransitionLayout, type: TYPE) {
+ updateMediaViewControllerType(type)
this.transitionLayout = transitionLayout
layoutController.attach(transitionLayout)
if (currentEndLocation == -1) {
@@ -426,7 +435,7 @@ class MediaViewController @Inject constructor(
viewState: TransitionViewState?,
location: Int,
outState: TransitionViewState
- ) : TransitionViewState? {
+ ): TransitionViewState? {
val result = viewState?.copy(outState) ?: return null
val overrideSize = mediaHostStatesManager.carouselSizes[location]
overrideSize?.let {
@@ -438,6 +447,18 @@ class MediaViewController @Inject constructor(
return result
}
+ private fun updateMediaViewControllerType(type: TYPE) {
+ this.type = type
+ if (type == TYPE.PLAYER) {
+ collapsedLayout.load(context, R.xml.media_collapsed)
+ expandedLayout.load(context, R.xml.media_expanded)
+ } else {
+ collapsedLayout.load(context, R.xml.media_recommendation)
+ expandedLayout.load(context, R.xml.media_recommendation)
+ }
+ refreshState()
+ }
+
/**
* Retrieves the [TransitionViewState] and [MediaHostState] of a [@MediaLocation].
* In the event of [location] not being visible, [locationWhenHidden] will be used instead.
diff --git a/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt
new file mode 100644
index 000000000000..ac201a804e38
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.annotation.IntegerRes
+import com.android.systemui.R
+import com.android.systemui.util.animation.TransitionLayout
+
+/** ViewHolder for a Smartspace media recommendation. */
+class RecommendationViewHolder private constructor(itemView: View) {
+
+ val recommendations = itemView as TransitionLayout
+ val mediaCoverItems = listOf<ImageView>(
+ itemView.requireViewById(R.id.media_cover1),
+ itemView.requireViewById(R.id.media_cover2),
+ itemView.requireViewById(R.id.media_cover3),
+ itemView.requireViewById(R.id.media_cover4))
+ val mediaLogoItems = listOf<ImageView>(
+ itemView.requireViewById(R.id.media_logo1),
+ itemView.requireViewById(R.id.media_logo2),
+ itemView.requireViewById(R.id.media_logo3),
+ itemView.requireViewById(R.id.media_logo4))
+ val mediaCoverItemsResIds = listOf<@IntegerRes Int>(
+ R.id.media_cover1,
+ R.id.media_cover2,
+ R.id.media_cover3,
+ R.id.media_cover4)
+ val mediaLogoItemsResIds = listOf<@IntegerRes Int>(
+ R.id.media_logo1,
+ R.id.media_logo2,
+ R.id.media_logo3,
+ R.id.media_logo4)
+
+ init {
+ (recommendations.background as IlluminationDrawable).let { background ->
+ mediaCoverItems.forEach { background.registerLightSource(it) }
+ mediaLogoItems.forEach { background.registerLightSource(it) }
+ }
+ }
+
+ companion object {
+ /**
+ * Creates a PlayerViewHolder.
+ *
+ * @param inflater LayoutInflater to use to inflate the layout.
+ * @param parent Parent of inflated view.
+ */
+ @JvmStatic fun create(inflater: LayoutInflater, parent: ViewGroup):
+ RecommendationViewHolder {
+ val itemView =
+ inflater.inflate(
+ R.layout.media_smartspace_recommendations,
+ parent,
+ false /* attachToRoot */)
+ // Because this media view (a TransitionLayout) is used to measure and layout the views
+ // in various states before being attached to its parent, we can't depend on the default
+ // LAYOUT_DIRECTION_INHERIT to correctly resolve the ltr direction.
+ itemView.layoutDirection = View.LAYOUT_DIRECTION_LOCALE
+ return RecommendationViewHolder(itemView)
+ }
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaDataProvider.kt b/packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaDataProvider.kt
new file mode 100644
index 000000000000..b6c2ef1db82a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaDataProvider.kt
@@ -0,0 +1,39 @@
+package com.android.systemui.media
+
+import android.app.smartspace.SmartspaceTarget
+import com.android.systemui.plugins.BcSmartspaceDataPlugin
+import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener
+import javax.inject.Inject
+
+/** Provides SmartspaceTargets of media types for SystemUI media control. */
+class SmartspaceMediaDataProvider @Inject constructor() : BcSmartspaceDataPlugin {
+
+ private val smartspaceMediaTargetListeners: MutableList<SmartspaceTargetListener> =
+ mutableListOf()
+ private var smartspaceMediaTargets: List<SmartspaceTarget> = listOf()
+
+ override fun registerListener(smartspaceTargetListener: SmartspaceTargetListener) {
+ smartspaceMediaTargetListeners.add(smartspaceTargetListener)
+ }
+
+ override fun unregisterListener(smartspaceTargetListener: SmartspaceTargetListener?) {
+ smartspaceMediaTargetListeners.remove(smartspaceTargetListener)
+ }
+
+ /** Updates Smartspace data and propagates it to any listeners. */
+ override fun onTargetsAvailable(targets: List<SmartspaceTarget>) {
+ // Filter out non-media targets.
+ val mediaTargets = mutableListOf<SmartspaceTarget>()
+ for (target in targets) {
+ val smartspaceTarget = target
+ if (smartspaceTarget.featureType == SmartspaceTarget.FEATURE_MEDIA) {
+ mediaTargets.add(smartspaceTarget)
+ }
+ }
+
+ smartspaceMediaTargets = mediaTargets
+ smartspaceMediaTargetListeners.forEach {
+ it.onSmartspaceTargetsUpdated(smartspaceMediaTargets)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
index f1d4804aa622..c6373f5e0c5f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -41,8 +41,8 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.media.MediaDevice;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
/**
* Base adapter for media output dialog.
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index 339331bdd827..a8c4d6ef9085 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -67,8 +67,8 @@ import android.widget.FrameLayout;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
import com.android.systemui.navigationbar.buttons.ContextualButton;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/RotationButtonController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/RotationButtonController.java
index 33d180758f93..4bcb0193c7d0 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/RotationButtonController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/RotationButtonController.java
@@ -44,8 +44,8 @@ import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.navigationbar.buttons.KeyButtonDrawable;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java
index a4f5548a659c..4d250797f944 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java
@@ -16,7 +16,7 @@
package com.android.systemui.navigationbar.buttons;
-import static com.android.systemui.Interpolators.LINEAR;
+import static com.android.systemui.animation.Interpolators.LINEAR;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonRipple.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonRipple.java
index cf45f52e3367..e3e2367aeef8 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonRipple.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonRipple.java
@@ -34,8 +34,8 @@ import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.Interpolator;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import java.util.ArrayList;
import java.util.HashSet;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
index ac9f183c6ff3..9c82989531aa 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
@@ -51,8 +51,8 @@ import androidx.dynamicanimation.animation.SpringForce;
import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.plugins.NavigationEdgeBackPlugin;
import com.android.systemui.statusbar.VibratorHelper;
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
index 02c12f6d51e5..a0b55218c0fc 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
@@ -29,7 +29,6 @@ import android.app.people.PeopleSpaceTile;
import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherApps;
-import android.content.pm.PackageManager;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Outline;
@@ -60,7 +59,6 @@ public class PeopleSpaceActivity extends Activity {
private IPeopleManager mPeopleManager;
private PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
private INotificationManager mNotificationManager;
- private PackageManager mPackageManager;
private LauncherApps mLauncherApps;
private Context mContext;
private NotificationEntryManager mNotificationEntryManager;
@@ -81,7 +79,6 @@ public class PeopleSpaceActivity extends Activity {
mContext = getApplicationContext();
mNotificationManager = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
- mPackageManager = getPackageManager();
mPeopleManager = IPeopleManager.Stub.asInterface(
ServiceManager.getService(Context.PEOPLE_SERVICE));
mLauncherApps = mContext.getSystemService(LauncherApps.class);
@@ -112,7 +109,7 @@ public class PeopleSpaceActivity extends Activity {
LinearLayout item = findViewById(R.id.item);
GradientDrawable shape = (GradientDrawable) item.getBackground();
final TypedArray ta = mContext.obtainStyledAttributes(
- new int[] {android.R.attr.colorBackgroundFloating});
+ new int[]{android.R.attr.colorBackgroundFloating});
shape.setColor(ta.getColor(0, Color.WHITE));
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
index 3bc91bc5a4ed..51af47d92d7b 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
@@ -33,6 +33,7 @@ import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH;
import static com.android.systemui.people.PeopleSpaceUtils.convertDrawableToBitmap;
import static com.android.systemui.people.PeopleSpaceUtils.getUserId;
+import android.annotation.ColorInt;
import android.annotation.Nullable;
import android.app.PendingIntent;
import android.app.people.ConversationStatus;
@@ -40,6 +41,7 @@ import android.app.people.PeopleSpaceTile;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
+import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
@@ -48,12 +50,13 @@ import android.os.Bundle;
import android.text.TextUtils;
import android.util.IconDrawableFactory;
import android.util.Log;
-import android.util.TypedValue;
+import android.view.ContextThemeWrapper;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.people.widget.LaunchConversationActivity;
import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
@@ -344,10 +347,11 @@ class PeopleTileViewHelper {
setMaxLines(views);
CharSequence content = mTile.getNotificationContent();
views = setPunctuationRemoteViewsFields(views, content);
- TypedValue typedValue = new TypedValue();
- mContext.getTheme().resolveAttribute(android.R.attr.textColorPrimary, typedValue, true);
- int primaryTextColor = mContext.getColor(typedValue.resourceId);
- views.setInt(R.id.text_content, "setTextColor", primaryTextColor);
+ // TODO(b/184931139): Update to RemoteViews wrapper to set via attribute once available
+ @ColorInt int color = Utils.getColorAttr(mContext,
+ android.R.attr.textColorPrimary).getDefaultColor();
+ views.setInt(R.id.text_content, "setTextColor", color);
+
views.setTextViewText(R.id.text_content, mTile.getNotificationContent());
views.setViewVisibility(R.id.image, View.GONE);
views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_message);
@@ -394,10 +398,9 @@ class PeopleTileViewHelper {
views.setViewVisibility(R.id.messages_count, View.GONE);
setMaxLines(views);
// Secondary text color for statuses.
- TypedValue typedValue = new TypedValue();
- mContext.getTheme().resolveAttribute(android.R.attr.textColorSecondary, typedValue, true);
- int secondaryTextColor = mContext.getColor(typedValue.resourceId);
- views.setInt(R.id.text_content, "setTextColor", secondaryTextColor);
+ @ColorInt int secondaryColor = Utils.getColorAttr(mContext,
+ android.R.attr.textColorSecondary).getDefaultColor();
+ views.setInt(R.id.text_content, "setTextColor", secondaryColor);
views.setTextViewText(R.id.text_content, statusText);
Icon statusIcon = status.getIcon();
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
index 117be476e802..d63dc4ae6616 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
@@ -95,6 +95,7 @@ public class PeopleSpaceWidgetManager {
private PeopleManager mPeopleManager;
private NotificationEntryManager mNotificationEntryManager;
private PackageManager mPackageManager;
+ private PeopleSpaceWidgetProvider mPeopleSpaceWidgetProvider;
public UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
@GuardedBy("mLock")
public static Map<PeopleTileKey, PeopleSpaceWidgetProvider.TileConversationListener>
@@ -119,6 +120,7 @@ public class PeopleSpaceWidgetManager {
mPeopleManager = mContext.getSystemService(PeopleManager.class);
mNotificationEntryManager = Dependency.get(NotificationEntryManager.class);
mPackageManager = mContext.getPackageManager();
+ mPeopleSpaceWidgetProvider = new PeopleSpaceWidgetProvider();
}
/**
@@ -129,7 +131,7 @@ public class PeopleSpaceWidgetManager {
AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager,
PeopleManager peopleManager, LauncherApps launcherApps,
NotificationEntryManager notificationEntryManager, PackageManager packageManager,
- boolean isForTesting) {
+ boolean isForTesting, PeopleSpaceWidgetProvider peopleSpaceWidgetProvider) {
mAppWidgetManager = appWidgetManager;
mIPeopleManager = iPeopleManager;
mPeopleManager = peopleManager;
@@ -137,6 +139,7 @@ public class PeopleSpaceWidgetManager {
mNotificationEntryManager = notificationEntryManager;
mPackageManager = packageManager;
mIsForTesting = isForTesting;
+ mPeopleSpaceWidgetProvider = peopleSpaceWidgetProvider;
}
/**
@@ -616,7 +619,20 @@ public class PeopleSpaceWidgetManager {
return;
}
- mUiEventLogger.log(PeopleSpaceUtils.PeopleSpaceWidgetEvent.PEOPLE_SPACE_WIDGET_ADDED);
+ PeopleTileKey existingKeyIfStored;
+ synchronized (mLock) {
+ existingKeyIfStored = getKeyFromStorageByWidgetId(appWidgetId);
+ }
+ // Delete previous storage if the widget already existed and is just reconfigured.
+ if (existingKeyIfStored.isValid()) {
+ if (DEBUG) Log.d(TAG, "Remove previous storage for widget: " + appWidgetId);
+ deleteWidgets(new int[]{appWidgetId});
+ } else {
+ // Widget newly added.
+ mUiEventLogger.log(
+ PeopleSpaceUtils.PeopleSpaceWidgetEvent.PEOPLE_SPACE_WIDGET_ADDED);
+ }
+
synchronized (mLock) {
if (DEBUG) Log.d(TAG, "Add storage for : " + tile.getId());
PeopleTileKey key = new PeopleTileKey(tile);
@@ -634,8 +650,7 @@ public class PeopleSpaceWidgetManager {
PeopleSpaceUtils.updateAppWidgetOptionsAndView(
mAppWidgetManager, mContext, appWidgetId, tile);
- PeopleSpaceWidgetProvider provider = new PeopleSpaceWidgetProvider();
- provider.onUpdate(mContext, mAppWidgetManager, new int[]{appWidgetId});
+ mPeopleSpaceWidgetProvider.onUpdate(mContext, mAppWidgetManager, new int[]{appWidgetId});
}
/** Registers a conversation listener for {@code appWidgetId} if not already registered. */
@@ -644,12 +659,7 @@ public class PeopleSpaceWidgetManager {
// Retrieve storage needed for registration.
PeopleTileKey key;
synchronized (mLock) {
- SharedPreferences widgetSp = mContext.getSharedPreferences(String.valueOf(widgetId),
- Context.MODE_PRIVATE);
- key = new PeopleTileKey(
- widgetSp.getString(SHORTCUT_ID, EMPTY_STRING),
- widgetSp.getInt(USER_ID, INVALID_USER_ID),
- widgetSp.getString(PACKAGE_NAME, EMPTY_STRING));
+ key = getKeyFromStorageByWidgetId(widgetId);
if (!key.isValid()) {
if (DEBUG) Log.w(TAG, "Could not register listener for widget: " + widgetId);
return;
@@ -669,6 +679,20 @@ public class PeopleSpaceWidgetManager {
mContext.getMainExecutor());
}
+ /**
+ * Attempts to get a key from storage for {@code widgetId}, returning null if an invalid key is
+ * found.
+ */
+ private PeopleTileKey getKeyFromStorageByWidgetId(int widgetId) {
+ SharedPreferences widgetSp = mContext.getSharedPreferences(String.valueOf(widgetId),
+ Context.MODE_PRIVATE);
+ PeopleTileKey key = new PeopleTileKey(
+ widgetSp.getString(SHORTCUT_ID, EMPTY_STRING),
+ widgetSp.getInt(USER_ID, INVALID_USER_ID),
+ widgetSp.getString(PACKAGE_NAME, EMPTY_STRING));
+ return key;
+ }
+
/** Deletes all storage, listeners, and caching for {@code appWidgetIds}. */
public void deleteWidgets(int[] appWidgetIds) {
for (int widgetId : appWidgetIds) {
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
index 8ec9b682ffdc..dc22dc17cb85 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
@@ -128,9 +128,14 @@ class PrivacyDialog(
)
} ?: firstLine
newView.requireViewById<TextView>(R.id.text).text = finalText
+ if (element.phoneCall) {
+ newView.requireViewById<View>(R.id.chevron).visibility = View.GONE
+ }
newView.apply {
setTag(element)
- setOnClickListener(clickListener)
+ if (!element.phoneCall) {
+ setOnClickListener(clickListener)
+ }
}
return newView
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 5256bc45b7b5..586176f1c385 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -24,6 +24,7 @@ import android.graphics.Point;
import android.util.AttributeSet;
import android.util.Pair;
import android.view.View;
+import android.view.WindowInsets;
import android.widget.FrameLayout;
import androidx.dynamicanimation.animation.FloatPropertyCompat;
@@ -70,6 +71,7 @@ public class QSContainerImpl extends FrameLayout {
private boolean mBackgroundVisible;
private int mContentPadding = -1;
private boolean mAnimateBottomOnNextLayout;
+ private int mNavBarInset = 0;
public QSContainerImpl(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -137,6 +139,12 @@ public class QSContainerImpl extends FrameLayout {
}
@Override
+ public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+ mNavBarInset = insets.getInsets(WindowInsets.Type.navigationBars()).bottom;
+ return super.onApplyWindowInsets(insets);
+ }
+
+ @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// QSPanel will show as many rows as it can (up to TileLayout.MAX_ROWS) such that the
// bottom and footer are inside the screen.
@@ -146,7 +154,7 @@ public class QSContainerImpl extends FrameLayout {
// subtract its height. We do not care if the collapsed notifications fit in the screen.
int maxQs = getDisplayHeight() - layoutParams.topMargin - layoutParams.bottomMargin
- getPaddingBottom();
-
+ maxQs -= mNavBarInset;
int padding = mPaddingLeft + mPaddingRight + layoutParams.leftMargin
+ layoutParams.rightMargin;
final int qsPanelWidthSpec = getChildMeasureSpec(widthMeasureSpec, padding,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index cb58eff650c1..b95194adb9cc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -36,8 +36,8 @@ import android.widget.FrameLayout.LayoutParams;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.media.MediaHost;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
index 2c5dbcd51f21..670475fac5ef 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
@@ -36,7 +36,6 @@ import android.text.SpannableStringBuilder;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.util.Log;
-import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@@ -89,7 +88,7 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen
private Drawable mPrimaryFooterIconDrawable;
@Inject
- QSSecurityFooter(@Named(QS_SECURITY_FOOTER_VIEW) View rootView, Context context,
+ QSSecurityFooter(@Named(QS_SECURITY_FOOTER_VIEW) View rootView,
UserTracker userTracker, @Main Handler mainHandler, ActivityStarter activityStarter,
SecurityController securityController, @Background Looper bgLooper) {
mRootView = rootView;
@@ -98,7 +97,7 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen
mFooterIcon = mRootView.findViewById(R.id.footer_icon);
mPrimaryFooterIcon = mRootView.findViewById(R.id.primary_footer_icon);
mFooterIconId = R.drawable.ic_info_outline;
- mContext = context;
+ mContext = rootView.getContext();
mMainHandler = mainHandler;
mActivityStarter = activityStarter;
mSecurityController = securityController;
@@ -308,7 +307,7 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen
}
private void createDialog() {
- mDialog = new SystemUIDialog(mContext);
+ mDialog = new SystemUIDialog(mContext, 0); // Use mContext theme
mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(), this);
mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getNegativeButton(), this);
@@ -344,8 +343,7 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen
final String vpnNameWorkProfile = mSecurityController.getWorkProfileVpnName();
- View dialogView = LayoutInflater.from(
- new ContextThemeWrapper(mContext, R.style.Theme_SystemUI_Dialog))
+ View dialogView = LayoutInflater.from(mContext)
.inflate(R.layout.quick_settings_footer_dialog, null, false);
// device management section
@@ -420,8 +418,7 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen
}
private View createParentalControlsDialogView() {
- View dialogView = LayoutInflater.from(
- new ContextThemeWrapper(mContext, R.style.Theme_SystemUI_Dialog))
+ View dialogView = LayoutInflater.from(mContext)
.inflate(R.layout.quick_settings_footer_dialog_parental_controls, null, false);
DeviceAdminInfo info = mSecurityController.getDeviceAdminInfo();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index b661e2b6ae57..3f063125ef85 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -35,8 +35,8 @@ import android.widget.Space;
import com.android.settingslib.Utils;
import com.android.systemui.BatteryMeterView;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.qs.QSDetail.Callback;
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 6f789d3c8541..30a08c6f1b66 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -22,7 +22,6 @@ import android.content.Context;
import android.content.res.Configuration;
import android.util.AttributeSet;
import android.util.TypedValue;
-import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
@@ -63,7 +62,7 @@ public class QSCustomizer extends LinearLayout {
private boolean mIsShowingNavBackdrop;
public QSCustomizer(Context context, AttributeSet attrs) {
- super(new ContextThemeWrapper(context, R.style.Theme_SystemUI_QuickSettings_Edit), attrs);
+ super(context, attrs);
LayoutInflater.from(getContext()).inflate(R.layout.qs_customize_panel_content, this);
mClipper = new QSDetailClipper(findViewById(R.id.customize_container));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 08aa599d34b7..006b23098622 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -52,6 +52,7 @@ import com.android.systemui.qs.customize.TileAdapter.Holder;
import com.android.systemui.qs.customize.TileQueryHelper.TileInfo;
import com.android.systemui.qs.customize.TileQueryHelper.TileStateListener;
import com.android.systemui.qs.dagger.QSScope;
+import com.android.systemui.qs.dagger.QSThemedContext;
import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.qs.tileimpl.QSIconViewImpl;
import com.android.systemui.qs.tileimpl.QSTileView;
@@ -89,7 +90,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
private final Handler mHandler = new Handler();
private final List<TileInfo> mTiles = new ArrayList<>();
private final ItemTouchHelper mItemTouchHelper;
- private final ItemDecoration mDecoration;
+ private ItemDecoration mDecoration;
private final MarginTileDecoration mMarginDecoration;
private final int mMinNumTiles;
private final QSTileHost mHost;
@@ -112,8 +113,12 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
private final boolean mUseHorizontalTiles;
@Inject
- public TileAdapter(Context context, QSTileHost qsHost, UiEventLogger uiEventLogger,
- @Named(QS_LABELS_FLAG) boolean useHorizontalTiles) {
+ public TileAdapter(
+ @QSThemedContext Context context,
+ QSTileHost qsHost,
+ UiEventLogger uiEventLogger,
+ @Named(QS_LABELS_FLAG) boolean useHorizontalTiles
+ ) {
mContext = context;
mHost = qsHost;
mUiEventLogger = uiEventLogger;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
index 2363aa455cce..3a5adce51d0d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
@@ -49,6 +49,22 @@ public interface QSFragmentModule {
String QS_SECURITY_FOOTER_VIEW = "qs_security_footer";
String QS_USING_MEDIA_PLAYER = "qs_using_media_player";
+ /**
+ * Provide a context themed using the QS theme
+ */
+ @Provides
+ @QSThemedContext
+ static Context provideThemedContext(@RootView View view) {
+ return view.getContext();
+ }
+
+ /** */
+ @Provides
+ @QSThemedContext
+ static LayoutInflater provideThemedLayoutInflater(@QSThemedContext Context context) {
+ return LayoutInflater.from(context);
+ }
+
/** */
@Provides
@RootView
@@ -109,7 +125,10 @@ public interface QSFragmentModule {
@Provides
@QSScope
@Named(QS_SECURITY_FOOTER_VIEW)
- static View providesQSSecurityFooterView(LayoutInflater layoutInflater, QSPanel qsPanel) {
+ static View providesQSSecurityFooterView(
+ @QSThemedContext LayoutInflater layoutInflater,
+ QSPanel qsPanel
+ ) {
return layoutInflater.inflate(R.layout.quick_settings_footer, qsPanel, false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSThemedContext.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSThemedContext.java
new file mode 100644
index 000000000000..a878d4c60f88
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSThemedContext.java
@@ -0,0 +1,32 @@
+/*
+ * 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.qs.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+/**
+ * Annotation for themed context in QS
+ */
+@Documented
+@Retention(RUNTIME)
+@Qualifier
+public @interface QSThemedContext {}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
index abe321979a1a..7e72f1a18e41 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
@@ -72,7 +72,6 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
protected final ImageView mBg;
private final int mColorActive;
private final int mColorInactive;
- private final int mColorDisabled;
private int mCircleColor;
private int mBgSize;
@@ -131,10 +130,9 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
setBackground(mTileBackground);
- mColorActive = Utils.getColorAttrDefaultColor(context, android.R.attr.colorAccent);
- mColorDisabled = Utils.getDisabled(context,
- Utils.getColorAttrDefaultColor(context, android.R.attr.colorControlActivated));
- mColorInactive = Utils.getColorAttrDefaultColor(context, android.R.attr.textColorSecondary);
+ mColorActive = Utils.getColorAttrDefaultColor(context,
+ com.android.internal.R.attr.colorAccentPrimary);
+ mColorInactive = Utils.getColorAttrDefaultColor(context, R.attr.offStateColor);
setPadding(0, 0, 0, 0);
setClipChildren(false);
@@ -324,7 +322,7 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
return mColorActive;
case Tile.STATE_INACTIVE:
case Tile.STATE_UNAVAILABLE:
- return mColorDisabled;
+ return mColorInactive;
default:
Log.e(TAG, "Invalid state " + state);
return 0;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 375c79f0aaf5..aa8ce85f5950 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -58,9 +58,9 @@ import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.Utils;
import com.android.systemui.Dumpable;
+import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.animation.ActivityLaunchAnimator;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSIconView;
import com.android.systemui.plugins.qs.QSTile;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
index 78ee89607570..9e11451afa06 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
@@ -28,21 +28,26 @@ import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
-import android.util.IntArray;
import android.util.Log;
import android.util.MathUtils;
import android.util.Range;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.SeekBar;
import androidx.annotation.Nullable;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
+import androidx.customview.widget.ExploreByTouchHelper;
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
-import com.android.internal.widget.ExploreByTouchHelper;
import com.android.systemui.R;
+import java.util.List;
+
/**
* CropView has top and bottom draggable crop handles, with a scrim to darken the areas being
* cropped out.
@@ -66,6 +71,7 @@ public class CropView extends View {
private int mImageWidth;
private CropBoundary mCurrentDraggingBoundary = CropBoundary.NONE;
+ private int mActivePointerId;
// The starting value of mCurrentDraggingBoundary's crop, used to compute touch deltas.
private float mMovementStartValue;
private float mStartingY; // y coordinate of ACTION_DOWN
@@ -74,6 +80,7 @@ public class CropView extends View {
private Range<Float> mMotionRange;
private CropInteractionListener mCropInteractionListener;
+ private final ExploreByTouchHelper mExploreByTouchHelper;
public CropView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
@@ -94,7 +101,8 @@ public class CropView extends View {
// 48 dp touchable region around each handle.
mCropTouchMargin = 24 * getResources().getDisplayMetrics().density;
- setAccessibilityDelegate(new AccessibilityHelper());
+ mExploreByTouchHelper = new AccessibilityHelper();
+ ViewCompat.setAccessibilityDelegate(this, mExploreByTouchHelper);
}
@Override
@@ -131,64 +139,88 @@ public class CropView extends View {
public boolean onTouchEvent(MotionEvent event) {
int topPx = fractionToVerticalPixels(mCrop.top);
int bottomPx = fractionToVerticalPixels(mCrop.bottom);
- switch (event.getAction()) {
+ switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mCurrentDraggingBoundary = nearestBoundary(event, topPx, bottomPx,
fractionToHorizontalPixels(mCrop.left),
fractionToHorizontalPixels(mCrop.right));
if (mCurrentDraggingBoundary != CropBoundary.NONE) {
+ mActivePointerId = event.getPointerId(0);
mStartingY = event.getY();
mStartingX = event.getX();
mMovementStartValue = getBoundaryPosition(mCurrentDraggingBoundary);
- updateListener(event);
- switch (mCurrentDraggingBoundary) {
- case TOP:
- mMotionRange = new Range<>(0f,
- mCrop.bottom - pixelDistanceToFraction(mCropTouchMargin,
- CropBoundary.BOTTOM));
- break;
- case BOTTOM:
- mMotionRange = new Range<>(
- mCrop.top + pixelDistanceToFraction(mCropTouchMargin,
- CropBoundary.TOP), 1f);
- break;
- case LEFT:
- mMotionRange = new Range<>(0f,
- mCrop.right - pixelDistanceToFraction(mCropTouchMargin,
- CropBoundary.RIGHT));
- break;
- case RIGHT:
- mMotionRange = new Range<>(
- mCrop.left + pixelDistanceToFraction(mCropTouchMargin,
- CropBoundary.LEFT), 1f);
- break;
- }
+ updateListener(MotionEvent.ACTION_DOWN, event.getX());
+ mMotionRange = getAllowedValues(mCurrentDraggingBoundary);
}
return true;
case MotionEvent.ACTION_MOVE:
if (mCurrentDraggingBoundary != CropBoundary.NONE) {
- float deltaPx = isVertical(mCurrentDraggingBoundary) ? event.getY() - mStartingY
- : event.getX() - mStartingX;
- float delta = pixelDistanceToFraction((int) deltaPx, mCurrentDraggingBoundary);
- setBoundaryPosition(mCurrentDraggingBoundary,
- mMotionRange.clamp(mMovementStartValue + delta));
- updateListener(event);
- invalidate();
+ int pointerIndex = event.findPointerIndex(mActivePointerId);
+ if (pointerIndex >= 0) {
+ // Original pointer still active, do the move.
+ float deltaPx = isVertical(mCurrentDraggingBoundary)
+ ? event.getY(pointerIndex) - mStartingY
+ : event.getX(pointerIndex) - mStartingX;
+ float delta = pixelDistanceToFraction((int) deltaPx,
+ mCurrentDraggingBoundary);
+ setBoundaryPosition(mCurrentDraggingBoundary,
+ mMotionRange.clamp(mMovementStartValue + delta));
+ updateListener(MotionEvent.ACTION_MOVE, event.getX(pointerIndex));
+ invalidate();
+ }
+ return true;
+ }
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN:
+ if (mActivePointerId == event.getPointerId(event.getActionIndex())
+ && mCurrentDraggingBoundary != CropBoundary.NONE) {
+ updateListener(MotionEvent.ACTION_DOWN, event.getX(event.getActionIndex()));
+ return true;
+ }
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ if (mActivePointerId == event.getPointerId(event.getActionIndex())
+ && mCurrentDraggingBoundary != CropBoundary.NONE) {
+ updateListener(MotionEvent.ACTION_UP, event.getX(event.getActionIndex()));
return true;
}
+ break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
- if (mCurrentDraggingBoundary != CropBoundary.NONE) {
- updateListener(event);
+ if (mCurrentDraggingBoundary != CropBoundary.NONE
+ && mActivePointerId == event.getPointerId(mActivePointerId)) {
+ updateListener(MotionEvent.ACTION_UP, event.getX(0));
+ return true;
}
+ break;
}
return super.onTouchEvent(event);
}
+ @Override
+ public boolean dispatchHoverEvent(MotionEvent event) {
+ return mExploreByTouchHelper.dispatchHoverEvent(event)
+ || super.dispatchHoverEvent(event);
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ return mExploreByTouchHelper.dispatchKeyEvent(event)
+ || super.dispatchKeyEvent(event);
+ }
+
+ @Override
+ public void onFocusChanged(boolean gainFocus, int direction,
+ Rect previouslyFocusedRect) {
+ super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+ mExploreByTouchHelper.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+ }
+
/**
* Set the given boundary to the given value without animation.
*/
public void setBoundaryPosition(CropBoundary boundary, float position) {
+ position = (float) getAllowedValues(boundary).clamp(position);
switch (boundary) {
case TOP:
mCrop.top = position;
@@ -280,12 +312,51 @@ public class CropView extends View {
mCropInteractionListener = listener;
}
- private void updateListener(MotionEvent event) {
- if (mCropInteractionListener != null && (isVertical(mCurrentDraggingBoundary))) {
+ private Range getAllowedValues(CropBoundary boundary) {
+ switch (boundary) {
+ case TOP:
+ return new Range<>(0f,
+ mCrop.bottom - pixelDistanceToFraction(mCropTouchMargin,
+ CropBoundary.BOTTOM));
+ case BOTTOM:
+ return new Range<>(
+ mCrop.top + pixelDistanceToFraction(mCropTouchMargin,
+ CropBoundary.TOP), 1f);
+ case LEFT:
+ return new Range<>(0f,
+ mCrop.right - pixelDistanceToFraction(mCropTouchMargin,
+ CropBoundary.RIGHT));
+ case RIGHT:
+ return new Range<>(
+ mCrop.left + pixelDistanceToFraction(mCropTouchMargin,
+ CropBoundary.LEFT), 1f);
+ }
+ return null;
+ }
+
+ /**
+ * @param action either ACTION_DOWN, ACTION_UP or ACTION_MOVE.
+ * @param x coordinate of the relevant pointer.
+ */
+ private void updateListener(int action, float x) {
+ if (mCropInteractionListener != null && isVertical(mCurrentDraggingBoundary)) {
float boundaryPosition = getBoundaryPosition(mCurrentDraggingBoundary);
- mCropInteractionListener.onCropMotionEvent(event, mCurrentDraggingBoundary,
- boundaryPosition, fractionToVerticalPixels(boundaryPosition),
- (mCrop.left + mCrop.right) / 2);
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ mCropInteractionListener.onCropDragStarted(mCurrentDraggingBoundary,
+ boundaryPosition, fractionToVerticalPixels(boundaryPosition),
+ (mCrop.left + mCrop.right) / 2, x);
+ break;
+ case MotionEvent.ACTION_MOVE:
+ mCropInteractionListener.onCropDragMoved(mCurrentDraggingBoundary,
+ boundaryPosition, fractionToVerticalPixels(boundaryPosition),
+ (mCrop.left + mCrop.right) / 2, x);
+ break;
+ case MotionEvent.ACTION_UP:
+ mCropInteractionListener.onCropDragComplete();
+ break;
+
+ }
}
}
@@ -371,6 +442,8 @@ public class CropView extends View {
private static final int TOP_HANDLE_ID = 1;
private static final int BOTTOM_HANDLE_ID = 2;
+ private static final int LEFT_HANDLE_ID = 3;
+ private static final int RIGHT_HANDLE_ID = 4;
AccessibilityHelper() {
super(CropView.this);
@@ -384,62 +457,125 @@ public class CropView extends View {
if (Math.abs(y - fractionToVerticalPixels(mCrop.bottom)) < mCropTouchMargin) {
return BOTTOM_HANDLE_ID;
}
- return ExploreByTouchHelper.INVALID_ID;
+ if (y > fractionToVerticalPixels(mCrop.top)
+ && y < fractionToVerticalPixels(mCrop.bottom)) {
+ if (Math.abs(x - fractionToHorizontalPixels(mCrop.left)) < mCropTouchMargin) {
+ return LEFT_HANDLE_ID;
+ }
+ if (Math.abs(x - fractionToHorizontalPixels(mCrop.right)) < mCropTouchMargin) {
+ return RIGHT_HANDLE_ID;
+ }
+ }
+
+ return ExploreByTouchHelper.HOST_ID;
}
@Override
- protected void getVisibleVirtualViews(IntArray virtualViewIds) {
+ protected void getVisibleVirtualViews(List<Integer> virtualViewIds) {
+ // Add views in traversal order
virtualViewIds.add(TOP_HANDLE_ID);
+ virtualViewIds.add(LEFT_HANDLE_ID);
+ virtualViewIds.add(RIGHT_HANDLE_ID);
virtualViewIds.add(BOTTOM_HANDLE_ID);
}
@Override
protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {
- switch (virtualViewId) {
- case TOP_HANDLE_ID:
- event.setContentDescription(
- getResources().getString(R.string.screenshot_top_boundary));
- break;
- case BOTTOM_HANDLE_ID:
- event.setContentDescription(
- getResources().getString(R.string.screenshot_bottom_boundary));
- break;
- }
+ CropBoundary boundary = viewIdToBoundary(virtualViewId);
+ event.setContentDescription(getBoundaryContentDescription(boundary));
}
@Override
protected void onPopulateNodeForVirtualView(int virtualViewId,
- AccessibilityNodeInfo node) {
- switch (virtualViewId) {
- case TOP_HANDLE_ID:
- node.setContentDescription(
- getResources().getString(R.string.screenshot_top_boundary));
- setNodePositions(mCrop.top, node);
+ AccessibilityNodeInfoCompat node) {
+ CropBoundary boundary = viewIdToBoundary(virtualViewId);
+ node.setContentDescription(getBoundaryContentDescription(boundary));
+ setNodePosition(getNodeRect(boundary), node);
+
+ // Intentionally set the class name to SeekBar so that TalkBack uses volume control to
+ // scroll.
+ node.setClassName(SeekBar.class.getName());
+ node.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD);
+ node.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD);
+ }
+
+ @Override
+ protected boolean onPerformActionForVirtualView(
+ int virtualViewId, int action, Bundle arguments) {
+ if (action != AccessibilityNodeInfo.ACTION_SCROLL_FORWARD
+ && action != AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) {
+ return false;
+ }
+ CropBoundary boundary = viewIdToBoundary(virtualViewId);
+ float delta = pixelDistanceToFraction(mCropTouchMargin, boundary);
+ if (action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD) {
+ delta = -delta;
+ }
+ setBoundaryPosition(boundary, delta + getBoundaryPosition(boundary));
+ invalidateVirtualView(virtualViewId);
+ sendEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_VIEW_SELECTED);
+ return true;
+ }
+
+ private CharSequence getBoundaryContentDescription(CropBoundary boundary) {
+ int template;
+ switch (boundary) {
+ case TOP:
+ template = R.string.screenshot_top_boundary_pct;
break;
- case BOTTOM_HANDLE_ID:
- node.setContentDescription(
- getResources().getString(R.string.screenshot_bottom_boundary));
- setNodePositions(mCrop.bottom, node);
+ case BOTTOM:
+ template = R.string.screenshot_bottom_boundary_pct;
+ break;
+ case LEFT:
+ template = R.string.screenshot_left_boundary_pct;
+ break;
+ case RIGHT:
+ template = R.string.screenshot_right_boundary_pct;
break;
+ default:
+ return "";
}
- // TODO: need to figure out the full set of actions to support here.
- node.addAction(
- AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK);
- node.setClickable(true);
- node.setFocusable(true);
+ return getResources().getString(template,
+ Math.round(getBoundaryPosition(boundary) * 100));
}
- @Override
- protected boolean onPerformActionForVirtualView(
- int virtualViewId, int action, Bundle arguments) {
- return false;
+ private CropBoundary viewIdToBoundary(int viewId) {
+ switch (viewId) {
+ case TOP_HANDLE_ID:
+ return CropBoundary.TOP;
+ case BOTTOM_HANDLE_ID:
+ return CropBoundary.BOTTOM;
+ case LEFT_HANDLE_ID:
+ return CropBoundary.LEFT;
+ case RIGHT_HANDLE_ID:
+ return CropBoundary.RIGHT;
+ }
+ return CropBoundary.NONE;
+ }
+
+ private Rect getNodeRect(CropBoundary boundary) {
+ Rect rect;
+ if (isVertical(boundary)) {
+ int pixels = fractionToVerticalPixels(getBoundaryPosition(boundary));
+ rect = new Rect(0, (int) (pixels - mCropTouchMargin),
+ getWidth(), (int) (pixels + mCropTouchMargin));
+ // Top boundary can sometimes go beyond the view, shift it down to compensate so
+ // the area is big enough.
+ if (rect.top < 0) {
+ rect.offset(0, -rect.top);
+ }
+ } else {
+ int pixels = fractionToHorizontalPixels(getBoundaryPosition(boundary));
+ rect = new Rect((int) (pixels - mCropTouchMargin),
+ (int) (fractionToVerticalPixels(mCrop.top) + mCropTouchMargin),
+ (int) (pixels + mCropTouchMargin),
+ (int) (fractionToVerticalPixels(mCrop.bottom) - mCropTouchMargin));
+ }
+ return rect;
}
- private void setNodePositions(float fraction, AccessibilityNodeInfo node) {
- int pixels = fractionToVerticalPixels(fraction);
- Rect rect = new Rect(0, (int) (pixels - mCropTouchMargin),
- getWidth(), (int) (pixels + mCropTouchMargin));
+ private void setNodePosition(Rect rect, AccessibilityNodeInfoCompat node) {
node.setBoundsInParent(rect);
int[] pos = new int[2];
getLocationOnScreen(pos);
@@ -452,12 +588,11 @@ public class CropView extends View {
* Listen for crop motion events and state.
*/
public interface CropInteractionListener {
- /**
- * Called whenever CropView has a MotionEvent that can impact the position of the crop
- * boundaries.
- */
- void onCropMotionEvent(MotionEvent event, CropBoundary boundary, float boundaryPosition,
- int boundaryPositionPx, float horizontalCenter);
+ void onCropDragStarted(CropBoundary boundary, float boundaryPosition,
+ int boundaryPositionPx, float horizontalCenter, float x);
+ void onCropDragMoved(CropBoundary boundary, float boundaryPosition,
+ int boundaryPositionPx, float horizontalCenter, float x);
+ void onCropDragComplete();
}
static class SavedState extends BaseSavedState {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index 9ce0eebfd441..33041d280b9b 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -207,6 +207,7 @@ public class LongScreenshotActivity extends Activity {
mLongScreenshot = longScreenshot;
mPreview.setImageDrawable(mLongScreenshot.getDrawable());
updateImageDimensions();
+ mCropView.setVisibility(View.VISIBLE);
mMagnifierView.setDrawable(mLongScreenshot.getDrawable(),
mLongScreenshot.getWidth(), mLongScreenshot.getHeight());
// Original boundaries go from the image tile set's y=0 to y=pageSize, so
@@ -240,6 +241,7 @@ public class LongScreenshotActivity extends Activity {
mPreview.setImageDrawable(drawable);
mMagnifierView.setDrawable(drawable, imageResult.bitmap.getWidth(),
imageResult.bitmap.getHeight());
+ mCropView.setVisibility(View.VISIBLE);
mSavedImagePath = imageResult.fileName;
setButtonsEnabled(true);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java b/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java
index 08cd91ccada5..34b40f79836b 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java
@@ -28,7 +28,6 @@ import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewPropertyAnimator;
@@ -148,49 +147,51 @@ public class MagnifierView extends View implements CropView.CropInteractionListe
}
@Override
- public void onCropMotionEvent(MotionEvent event, CropView.CropBoundary boundary,
- float cropPosition, int cropPositionPx, float horizontalCenter) {
+ public void onCropDragStarted(CropView.CropBoundary boundary, float boundaryPosition,
+ int boundaryPositionPx, float horizontalCenter, float x) {
mCropBoundary = boundary;
mLastCenter = horizontalCenter;
- boolean touchOnRight = event.getX() > getParentWidth() / 2;
+ boolean touchOnRight = x > getParentWidth() / 2;
float translateXTarget = touchOnRight ? 0 : getParentWidth() - getWidth();
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- mLastCropPosition = cropPosition;
- setTranslationY(cropPositionPx - getHeight() / 2);
- setPivotX(getWidth() / 2);
- setPivotY(getHeight() / 2);
- setScaleX(0.2f);
- setScaleY(0.2f);
- setAlpha(0f);
- setTranslationX((getParentWidth() - getWidth()) / 2);
- setVisibility(View.VISIBLE);
- mTranslationAnimator =
- animate().alpha(1f).translationX(translateXTarget).scaleX(1f).scaleY(1f);
- mTranslationAnimator.setListener(mTranslationAnimatorListener);
- mTranslationAnimator.start();
- break;
- case MotionEvent.ACTION_MOVE:
- // The touch is near the middle if it's within 10% of the center point.
- // We don't want to animate horizontally if the touch is near the middle.
- boolean nearMiddle = Math.abs(event.getX() - getParentWidth() / 2)
- < getParentWidth() / 10f;
- boolean viewOnLeft = getTranslationX() < (getParentWidth() - getWidth()) / 2;
- if (!nearMiddle && viewOnLeft != touchOnRight && mTranslationAnimator == null) {
- mTranslationAnimator = animate().translationX(translateXTarget);
- mTranslationAnimator.setListener(mTranslationAnimatorListener);
- mTranslationAnimator.start();
- }
- mLastCropPosition = cropPosition;
- setTranslationY(cropPositionPx - getHeight() / 2);
- invalidate();
- break;
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP:
- animate().alpha(0).translationX((getParentWidth() - getWidth()) / 2).scaleX(0.2f)
- .scaleY(0.2f).withEndAction(() -> setVisibility(View.INVISIBLE)).start();
- break;
+ mLastCropPosition = boundaryPosition;
+ setTranslationY(boundaryPositionPx - getHeight() / 2);
+ setPivotX(getWidth() / 2);
+ setPivotY(getHeight() / 2);
+ setScaleX(0.2f);
+ setScaleY(0.2f);
+ setAlpha(0f);
+ setTranslationX((getParentWidth() - getWidth()) / 2);
+ setVisibility(View.VISIBLE);
+ mTranslationAnimator =
+ animate().alpha(1f).translationX(translateXTarget).scaleX(1f).scaleY(1f);
+ mTranslationAnimator.setListener(mTranslationAnimatorListener);
+ mTranslationAnimator.start();
+ }
+
+ @Override
+ public void onCropDragMoved(CropView.CropBoundary boundary, float boundaryPosition,
+ int boundaryPositionPx, float horizontalCenter, float x) {
+ boolean touchOnRight = x > getParentWidth() / 2;
+ float translateXTarget = touchOnRight ? 0 : getParentWidth() - getWidth();
+ // The touch is near the middle if it's within 10% of the center point.
+ // We don't want to animate horizontally if the touch is near the middle.
+ boolean nearMiddle = Math.abs(x - getParentWidth() / 2)
+ < getParentWidth() / 10f;
+ boolean viewOnLeft = getTranslationX() < (getParentWidth() - getWidth()) / 2;
+ if (!nearMiddle && viewOnLeft != touchOnRight && mTranslationAnimator == null) {
+ mTranslationAnimator = animate().translationX(translateXTarget);
+ mTranslationAnimator.setListener(mTranslationAnimatorListener);
+ mTranslationAnimator.start();
}
+ mLastCropPosition = boundaryPosition;
+ setTranslationY(boundaryPositionPx - getHeight() / 2);
+ invalidate();
+ }
+
+ @Override
+ public void onCropDragComplete() {
+ animate().alpha(0).translationX((getParentWidth() - getWidth()) / 2).scaleX(0.2f)
+ .scaleY(0.2f).withEndAction(() -> setVisibility(View.INVISIBLE)).start();
}
private Path generateCheckerboard() {
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
index 1961bfc9ee27..3ba46460be43 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
@@ -25,6 +25,7 @@ import android.view.WindowManager;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import javax.inject.Inject;
@@ -61,10 +62,10 @@ public class BrightnessDialog extends Activity {
window.setLayout(
WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
-
BrightnessSlider controller = mToggleSliderFactory.create(this, null);
controller.init();
setContentView(controller.getRootView());
+ controller.getRootView().setBackgroundResource(R.drawable.brightness_mirror_background);
mBrightnessController = new BrightnessController(this, controller, mBroadcastDispatcher);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
index 952597556faf..63179dac7b8c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
@@ -18,8 +18,8 @@ package com.android.systemui.statusbar;
import android.view.View;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
index 5cebf7c04b7e..037812312aa7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
@@ -29,8 +29,8 @@ import android.view.ViewConfiguration;
import com.android.systemui.ExpandHelper;
import com.android.systemui.Gefingerpoken;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.notification.row.ExpandableView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
index f51fbedebad2..ec3a857dbc84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
@@ -97,4 +97,8 @@ public class FeatureFlags {
public boolean isOngoingCallStatusBarChipEnabled() {
return mFlagReader.isEnabled(R.bool.flag_ongoing_call_status_bar_chip);
}
+
+ public boolean isSmartspaceEnabled() {
+ return mFlagReader.isEnabled(R.bool.flag_smartspace);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index 4b9d5924a8d2..54b341f529b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -38,8 +38,8 @@ import android.view.ViewAnimationUtils;
import android.view.animation.Interpolator;
import android.widget.ImageView;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.wm.shell.animation.FlingAnimationUtils;
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 9804b32376eb..c1eaaaf92d52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -20,7 +20,6 @@ import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
-import static com.android.keyguard.KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1;
import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT;
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY;
@@ -30,6 +29,7 @@ import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewCont
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_RESTING;
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_TRUST;
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_USER_LOCKED;
+import static com.android.systemui.plugins.FalsingManager.LOW_PENALTY;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -69,14 +69,15 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.settingslib.Utils;
import com.android.settingslib.fuelgauge.BatteryStatus;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.KeyguardIndication;
import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -120,6 +121,7 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
private final @Main DelayableExecutor mExecutor;
private final LockPatternUtils mLockPatternUtils;
private final IActivityManager mIActivityManager;
+ private final FalsingManager mFalsingManager;
protected KeyguardIndicationRotateTextViewController mRotateTextViewController;
private BroadcastReceiver mBroadcastReceiver;
@@ -171,7 +173,8 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
DevicePolicyManager devicePolicyManager,
IBatteryStats iBatteryStats,
UserManager userManager,
- @Main DelayableExecutor executor) {
+ @Main DelayableExecutor executor,
+ FalsingManager falsingManager) {
mContext = context;
mBroadcastDispatcher = broadcastDispatcher;
mDevicePolicyManager = devicePolicyManager;
@@ -188,6 +191,7 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
mExecutor = executor;
mLockPatternUtils = new LockPatternUtils(context);
mIActivityManager = ActivityManager.getService();
+ mFalsingManager = falsingManager;
mKeyguardUpdateMonitor.registerCallback(getKeyguardCallback());
mKeyguardUpdateMonitor.registerCallback(mTickReceiver);
@@ -203,8 +207,7 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
mRotateTextViewController = new KeyguardIndicationRotateTextViewController(
indicationArea.findViewById(R.id.keyguard_indication_text_bottom),
mExecutor,
- mStatusBarStateController,
- mLockScreenMode);
+ mStatusBarStateController);
updateIndication(false /* animate */);
updateDisclosure();
if (mBroadcastReceiver == null) {
@@ -284,9 +287,7 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
mRotateTextViewController.hideIndication(INDICATION_TYPE_DISCLOSURE);
}
- if (isKeyguardLayoutEnabled()) {
- updateResting();
- }
+ updateResting();
}
private CharSequence getDisclosureText(@Nullable CharSequence organizationName) {
@@ -306,10 +307,6 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
}
private void updateOwnerInfo() {
- if (!isKeyguardLayoutEnabled()) {
- mRotateTextViewController.hideIndication(INDICATION_TYPE_OWNER_INFO);
- return;
- }
String info = mLockPatternUtils.getDeviceOwnerInfo();
if (info == null) {
// Use the current user owner information if enabled.
@@ -431,15 +428,7 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
}
}
- protected boolean isKeyguardLayoutEnabled() {
- return mLockScreenMode == LOCK_SCREEN_MODE_LAYOUT_1;
- }
-
private void updateLogoutView() {
- if (!isKeyguardLayoutEnabled()) {
- mRotateTextViewController.hideIndication(INDICATION_TYPE_LOGOUT);
- return;
- }
final boolean shouldShowLogout = mKeyguardUpdateMonitor.isLogoutEnabled()
&& KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM;
if (shouldShowLogout) {
@@ -452,6 +441,9 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
.setBackground(mContext.getDrawable(
com.android.systemui.R.drawable.logout_button_background))
.setClickListener((view) -> {
+ if (mFalsingManager.isFalseTap(LOW_PENALTY)) {
+ return;
+ }
int currentUserId = KeyguardUpdateMonitor.getCurrentUser();
try {
mIActivityManager.switchUser(UserHandle.USER_SYSTEM);
@@ -651,76 +643,8 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
}
// LOCK SCREEN
- // Some cases here might need to hide the indication (if the battery is not present)
- int userId = KeyguardUpdateMonitor.getCurrentUser();
-
- if (mLockScreenMode == LOCK_SCREEN_MODE_LAYOUT_1) {
- mTopIndicationView.setVisibility(GONE);
- updateIndications(animate, userId);
- } else {
- boolean hideIndication = false;
- boolean isError = false;
- String trustGrantedIndication = getTrustGrantedIndication();
- String trustManagedIndication = getTrustManagedIndication();
- String powerIndication = null;
-
- if (mPowerPluggedIn || mEnableBatteryDefender) {
- powerIndication = computePowerIndication();
- }
- if (!mKeyguardUpdateMonitor.isUserUnlocked(userId)) {
- mTopIndicationView.switchIndication(
- com.android.internal.R.string.lockscreen_storage_locked);
- } else if (!TextUtils.isEmpty(mTransientIndication)) {
- if (powerIndication != null && !mTransientIndication.equals(powerIndication)) {
- String indication = mContext.getResources().getString(
- R.string.keyguard_indication_trust_unlocked_plugged_in,
- mTransientIndication, powerIndication);
- mTopIndicationView.switchIndication(indication, null);
- hideIndication = !mBatteryPresent;
- } else {
- mTopIndicationView.switchIndication(mTransientIndication, null);
- }
- isError = mTransientTextIsError;
- } else if (!TextUtils.isEmpty(trustGrantedIndication)
- && mKeyguardUpdateMonitor.getUserHasTrust(userId)) {
- if (powerIndication != null) {
- String indication = mContext.getResources().getString(
- R.string.keyguard_indication_trust_unlocked_plugged_in,
- trustGrantedIndication, powerIndication);
- mTopIndicationView.switchIndication(indication, null);
- hideIndication = !mBatteryPresent;
- } else {
- mTopIndicationView.switchIndication(trustGrantedIndication, null);
- }
- } else if (!TextUtils.isEmpty(mAlignmentIndication)) {
- mTopIndicationView.switchIndication(mAlignmentIndication, null);
- isError = true;
- hideIndication = !mBatteryPresent;
- } else if (mPowerPluggedIn || mEnableBatteryDefender) {
- if (DEBUG_CHARGING_SPEED) {
- powerIndication += ", " + (mChargingWattage / 1000) + " mW";
- }
- if (animate) {
- animateText(mTopIndicationView, powerIndication);
- } else {
- mTopIndicationView.switchIndication(powerIndication, null);
- }
- hideIndication = !mBatteryPresent;
- } else if (!TextUtils.isEmpty(trustManagedIndication)
- && mKeyguardUpdateMonitor.getUserTrustIsManaged(userId)
- && !mKeyguardUpdateMonitor.getUserHasTrust(userId)) {
- mTopIndicationView.switchIndication(trustManagedIndication, null);
- } else {
- mTopIndicationView.switchIndication(mRestingIndication, null);
- }
-
- mTopIndicationView.setTextColor(
- isError ? Utils.getColorError(mContext) : mInitialTextColorState);
-
- if (hideIndication) {
- mIndicationArea.setVisibility(GONE);
- }
- }
+ mTopIndicationView.setVisibility(GONE);
+ updateIndications(animate, KeyguardUpdateMonitor.getCurrentUser());
}
// animates textView - textView moves up and bounces down
@@ -883,7 +807,7 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
@Override
public void onUnlockedChanged() {
- updateIndication(!mDozing);
+ updateIndication(false);
}
protected class BaseKeyguardCallback extends KeyguardUpdateMonitorCallback {
@@ -1025,7 +949,7 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal
@Override
public void onBiometricRunningStateChanged(boolean running,
BiometricSourceType biometricSourceType) {
- if (running) {
+ if (running && biometricSourceType == BiometricSourceType.FACE) {
// Let's hide any previous messages when authentication starts, otherwise
// multiple auth attempts would overlap.
hideTransientIndication();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
index 563470d1a260..d6921d448a69 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
@@ -13,7 +13,7 @@ import android.graphics.RadialGradient
import android.graphics.Shader
import android.util.AttributeSet
import android.view.View
-import com.android.systemui.Interpolators
+import com.android.systemui.animation.Interpolators
/**
* Provides methods to modify the various properties of a [LightRevealScrim] to reveal between 0% to
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index c565a271bdd7..27264880a462 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -24,6 +24,7 @@ import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Notification;
+import android.app.smartspace.SmartspaceTarget;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
@@ -49,7 +50,7 @@ import android.widget.ImageView;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
-import com.android.systemui.Interpolators;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.media.MediaData;
@@ -248,6 +249,11 @@ public class NotificationMediaManager implements Dumpable {
}
@Override
+ public void onSmartspaceMediaDataLoaded(@NonNull String key,
+ @NonNull SmartspaceTarget data) {
+ }
+
+ @Override
public void onMediaDataRemoved(@NonNull String key) {
mNotifPipeline.getAllNotifs()
.stream()
@@ -260,6 +266,9 @@ public class NotificationMediaManager implements Dumpable {
getDismissedByUserStats(entry));
});
}
+
+ @Override
+ public void onSmartspaceMediaDataRemoved(@NonNull String key) {}
});
}
@@ -313,6 +322,11 @@ public class NotificationMediaManager implements Dumpable {
}
@Override
+ public void onSmartspaceMediaDataLoaded(@NonNull String key,
+ @NonNull SmartspaceTarget data) {
+ }
+
+ @Override
public void onMediaDataRemoved(@NonNull String key) {
NotificationEntry entry = mEntryManager.getPendingOrActiveNotif(key);
if (entry != null) {
@@ -323,6 +337,9 @@ public class NotificationMediaManager implements Dumpable {
NotificationListenerService.REASON_CANCEL);
}
}
+
+ @Override
+ public void onSmartspaceMediaDataRemoved(@NonNull String key) {}
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index bb6165a07a24..2a468938ecff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -31,7 +31,7 @@ import androidx.dynamicanimation.animation.FloatPropertyCompat
import androidx.dynamicanimation.animation.SpringAnimation
import androidx.dynamicanimation.animation.SpringForce
import com.android.systemui.Dumpable
-import com.android.systemui.Interpolators
+import com.android.systemui.animation.Interpolators
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
index b7343f67a86d..84465a88eed0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
@@ -28,8 +28,8 @@ import android.view.MotionEvent
import android.view.VelocityTracker
import android.view.ViewConfiguration
import com.android.systemui.Gefingerpoken
-import com.android.systemui.Interpolators
import com.android.systemui.R
+import com.android.systemui.animation.Interpolators
import com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.dagger.SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 412d34261178..a00d01427ebc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -53,8 +53,8 @@ import androidx.core.graphics.ColorUtils;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.util.ContrastColorUtil;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.notification.NotificationIconDozeHelper;
import com.android.systemui.statusbar.notification.NotificationUtils;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index 5219ecd1d83c..9f59023f1890 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -36,7 +36,7 @@ import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.DejankUtils;
import com.android.systemui.Dumpable;
-import com.android.systemui.Interpolators;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java
index 7ecdc812cbd3..2fa27ee454e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java
@@ -25,8 +25,8 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.notification.TransformState;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ExpandAnimationParameters.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ExpandAnimationParameters.kt
index d5835fc6c50e..f1479a149a41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ExpandAnimationParameters.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ExpandAnimationParameters.kt
@@ -2,8 +2,8 @@ package com.android.systemui.statusbar.notification
import android.util.MathUtils
import com.android.internal.annotations.VisibleForTesting
-import com.android.systemui.Interpolators
-import com.android.systemui.plugins.animation.ActivityLaunchAnimator
+import com.android.systemui.animation.ActivityLaunchAnimator
+import com.android.systemui.animation.Interpolators
import kotlin.math.min
/** Parameters for the notifications expand animations. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
index 82f7c71c48cf..76025ab7aa7d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
@@ -21,8 +21,8 @@ import android.util.Pools;
import android.view.View;
import android.widget.ImageView;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.CrossFadeHelper;
import com.android.systemui.statusbar.TransformableView;
import com.android.systemui.statusbar.notification.row.HybridNotificationView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java
index e0532c3e2b28..c22cd1ba4bc8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingLayoutTransformState.java
@@ -29,7 +29,7 @@ import com.android.internal.widget.MessagingImageMessage;
import com.android.internal.widget.MessagingLinearLayout;
import com.android.internal.widget.MessagingMessage;
import com.android.internal.widget.MessagingPropertyAnimator;
-import com.android.systemui.Interpolators;
+import com.android.systemui.animation.Interpolators;
import java.util.ArrayList;
import java.util.HashMap;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
index 63bb73ab7f13..3fc7b132f38f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
@@ -24,8 +24,8 @@ import android.graphics.ColorMatrixColorFilter;
import android.view.View;
import android.widget.ImageView;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import java.util.function.Consumer;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
index 2f966b4e6d78..0b6a5c9703f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
@@ -2,11 +2,11 @@ package com.android.systemui.statusbar.notification
import android.view.View
import com.android.internal.jank.InteractionJankMonitor
+import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.statusbar.NotificationShadeDepthController
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.stack.NotificationListContainer
import com.android.systemui.statusbar.phone.NotificationPanelViewController
-import com.android.systemui.plugins.animation.ActivityLaunchAnimator
import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController
import kotlin.math.ceil
import kotlin.math.max
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index 50cbbd5d4852..c0fbf68768cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -18,7 +18,7 @@ package com.android.systemui.statusbar.notification
import android.animation.ObjectAnimator
import android.util.FloatProperty
-import com.android.systemui.Interpolators
+import com.android.systemui.animation.Interpolators
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.StatusBarState
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java
index 3517e245f624..5d07cac78682 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java
@@ -24,7 +24,7 @@ import android.util.Property;
import android.view.View;
import android.view.animation.Interpolator;
-import com.android.systemui.Interpolators;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.notification.stack.AnimationFilter;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.ViewState;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
index 20d10d3e0a6c..74e62b6afc19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
@@ -26,8 +26,8 @@ import android.widget.TextView;
import com.android.internal.widget.MessagingImageMessage;
import com.android.internal.widget.MessagingPropertyAnimator;
import com.android.internal.widget.ViewClippingUtil;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.CrossFadeHelper;
import com.android.systemui.statusbar.TransformableView;
import com.android.systemui.statusbar.ViewTransformationHelper;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt
index 847d1ccddddf..dc1627438490 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt
@@ -21,8 +21,8 @@ import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.view.View
import android.view.ViewGroup
-import com.android.systemui.Interpolators
import com.android.systemui.R
+import com.android.systemui.animation.Interpolators
/**
* Class to help with fading of view groups without fading one subview
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 17f70cb08218..78fcf18cfe6c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -36,8 +36,8 @@ import android.view.animation.PathInterpolator;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.settingslib.Utils;
import com.android.systemui.Gefingerpoken;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.notification.FakeShadowView;
import com.android.systemui.statusbar.notification.NotificationUtils;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 2ada28123f5f..8fae7200b56f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -73,12 +73,12 @@ import com.android.internal.widget.CachingIconView;
import com.android.internal.widget.CallLayout;
import com.android.internal.widget.MessagingLayout;
import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.ActivityLaunchAnimator;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.animation.ActivityLaunchAnimator;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index 73e080423d40..3190927dc24a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -29,8 +29,8 @@ import android.widget.FrameLayout;
import androidx.annotation.Nullable;
import com.android.systemui.Dumpable;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java
index 14683eca5080..c0bafb7a0d16 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java
@@ -147,7 +147,7 @@ public class FeedbackInfo extends LinearLayout implements NotificationGuts.GutsC
int status = mFeedbackController.getFeedbackStatus(mEntry);
if (DEBUG) {
sb.append(String.format(
- "[DEBUG]: oldImportance=%d, newImportance=%d, ranking=%d\n\n",
+ "[DEBUG]: oldImportance=%d, newImportance=%d, ranking=%f\n\n",
mRanking.getChannel().getImportance(), mRanking.getImportance(),
mRanking.getRankingScore()));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index 07d1e68aef80..af8b4d99792a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -29,9 +29,9 @@ import android.util.AttributeSet;
import android.view.View;
import com.android.internal.util.ArrayUtils;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
-import com.android.systemui.plugins.animation.ActivityLaunchAnimator;
+import com.android.systemui.animation.ActivityLaunchAnimator;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.notification.ExpandAnimationParameters;
/**
@@ -284,7 +284,7 @@ public class NotificationBackgroundView extends View {
mActualWidth = params.getWidth();
float alphaProgress = Interpolators.ALPHA_IN.getInterpolation(
params.getProgress(
- ActivityLaunchAnimator.ANIMATION_DURATION_FADE_OUT_CONTENT /* delay */,
+ ActivityLaunchAnimator.ANIMATION_DELAY_FADE_IN_WINDOW /* delay */,
ActivityLaunchAnimator.ANIMATION_DURATION_FADE_IN_WINDOW /* duration */));
mBackground.setAlpha((int) (mDrawableAlpha * (1.0f - alphaProgress)));
invalidate();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index 8ba036ce03c3..fa6f23d38984 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -24,7 +24,7 @@ import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static android.provider.Settings.Global.NOTIFICATION_BUBBLES;
-import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN;
+import static com.android.systemui.animation.Interpolators.FAST_OUT_SLOW_IN;
import static java.lang.annotation.RetentionPolicy.SOURCE;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
index 8ac5b933e4f9..fc296e125794 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
@@ -34,8 +34,8 @@ import android.widget.FrameLayout;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index d12d98ecc62b..59a78ed6f4ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -20,7 +20,7 @@ import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
-import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN;
+import static com.android.systemui.animation.Interpolators.FAST_OUT_SLOW_IN;
import static java.lang.annotation.RetentionPolicy.SOURCE;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index 2b12119ca0d6..c3dc7001f5e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -41,8 +41,8 @@ import android.widget.FrameLayout;
import android.widget.FrameLayout.LayoutParams;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.AlphaOptimizedImageView;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java
index 1ffb244b51c9..bfe352d57c24 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java
@@ -46,8 +46,8 @@ import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PriorityOnboardingDialogController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PriorityOnboardingDialogController.kt
index ae1285d3a5d7..9bbe616dc39d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PriorityOnboardingDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PriorityOnboardingDialogController.kt
@@ -41,9 +41,9 @@ import android.view.animation.Interpolator
import android.view.animation.PathInterpolator
import android.widget.ImageView
import android.widget.TextView
-import com.android.systemui.Interpolators.LINEAR_OUT_SLOW_IN
import com.android.systemui.Prefs
import com.android.systemui.R
+import com.android.systemui.animation.Interpolators.LINEAR_OUT_SLOW_IN
import com.android.systemui.people.widget.PeopleSpaceWidgetManager
import com.android.systemui.statusbar.notification.row.NotificationConversationInfo.OnConversationSettingsClickListener
import com.android.systemui.statusbar.phone.ShadeController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java
index 8d675f86c343..dba3401cc28e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java
@@ -23,7 +23,7 @@ import android.view.View;
import android.view.animation.Interpolator;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.Interpolators;
+import com.android.systemui.animation.Interpolators;
/**
* A common base class for all views in the notification stack scroller which don't have a
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index 5a55545351d0..15ca24edc996 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -36,7 +36,7 @@ import android.widget.TextView;
import com.android.internal.widget.CachingIconView;
import com.android.internal.widget.NotificationExpandButton;
-import com.android.systemui.Interpolators;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.TransformableView;
import com.android.systemui.statusbar.ViewTransformationHelper;
import com.android.systemui.statusbar.notification.CustomInterpolatorTransformation;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
index 628c4e258e50..b95d153e8bd1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
@@ -22,8 +22,8 @@ import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.view.View;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
index 1131a65abe93..ab39de0f9bc7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
@@ -26,7 +26,7 @@ import android.graphics.Rect;
import android.view.View;
import android.view.animation.Interpolator;
-import com.android.systemui.Interpolators;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.notification.ShadeViewRefactor;
import com.android.systemui.statusbar.notification.row.ExpandableView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index b28cc145dbab..fb72ac3c1411 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -77,8 +77,8 @@ import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
import com.android.systemui.ExpandHelper;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DragDownHelper.DragDownCallback;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
index 66a48f16b624..faeb12c0866f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
@@ -24,8 +24,8 @@ import android.view.View;
import android.view.animation.Interpolator;
import com.android.keyguard.KeyguardSliceView;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -65,6 +65,8 @@ public class StackStateAnimator {
public static final int ANIMATION_DELAY_HEADS_UP = 120;
public static final int ANIMATION_DELAY_HEADS_UP_CLICKED= 120;
private static final int MAX_STAGGER_COUNT = 5;
+ private static final HeadsUpAppearInterpolator HEADS_UP_APPEAR_INTERPOLATOR =
+ new HeadsUpAppearInterpolator();
private final int mGoToFullShadeAppearingTranslation;
private final int mPulsingAppearingTranslation;
@@ -118,7 +120,7 @@ public class StackStateAnimator {
@Override
public Interpolator getCustomInterpolator(View child, Property property) {
if (mHeadsUpAppearChildren.contains(child) && View.TRANSLATION_Y.equals(property)) {
- return Interpolators.HEADS_UP_APPEAR;
+ return HEADS_UP_APPEAR_INTERPOLATOR;
}
return null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
index 3da4e321c54d..df86e2012564 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
@@ -26,8 +26,8 @@ import android.view.View;
import android.view.animation.Interpolator;
import com.android.systemui.Dumpable;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.row.ExpandableView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
index c60bbc5f547f..9dce332985f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
@@ -34,8 +34,8 @@ import android.util.Log;
import android.view.View;
import com.android.settingslib.Utils;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index 9d1c60928106..40e6b40ffa14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -31,8 +31,8 @@ import android.view.ViewStub;
import android.widget.LinearLayout;
import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.StatusBarState;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
index 5dfb22faee7a..2922b4c98d34 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
@@ -25,8 +25,8 @@ import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.KeyguardAffordanceView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index b891e6f4552c..c3325b103022 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -48,8 +48,11 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.MediaStore;
-import android.provider.Settings;
import android.service.media.CameraPrewarmService;
+import android.service.quickaccesswallet.GetWalletCardsError;
+import android.service.quickaccesswallet.GetWalletCardsRequest;
+import android.service.quickaccesswallet.GetWalletCardsResponse;
+import android.service.quickaccesswallet.QuickAccessWalletClient;
import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -64,17 +67,20 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
+import androidx.annotation.NonNull;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.camera.CameraIntents;
import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.IntentButtonProvider;
import com.android.systemui.plugins.IntentButtonProvider.IntentButton;
import com.android.systemui.plugins.IntentButtonProvider.IntentButton.IconState;
@@ -87,6 +93,9 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.PreviewInflater;
import com.android.systemui.tuner.LockscreenFragment.LockButtonFactory;
import com.android.systemui.tuner.TunerService;
+import com.android.systemui.wallet.ui.WalletActivity;
+
+import java.util.concurrent.Executor;
/**
* Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
@@ -121,7 +130,13 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private KeyguardAffordanceView mRightAffordanceView;
private KeyguardAffordanceView mLeftAffordanceView;
+
private ImageView mWalletButton;
+ private boolean mWalletEnabled = false;
+ private boolean mHasCard = false;
+ private WalletCardRetriever mCardRetriever = new WalletCardRetriever();
+ private QuickAccessWalletClient mQuickAccessWalletClient;
+
private ViewGroup mIndicationArea;
private TextView mIndicationText;
private TextView mIndicationTextBottom;
@@ -138,7 +153,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private AccessibilityController mAccessibilityController;
private StatusBar mStatusBar;
private KeyguardAffordanceHelper mAffordanceHelper;
-
+ private FalsingManager mFalsingManager;
private boolean mUserSetupComplete;
private boolean mPrewarmBound;
private Messenger mPrewarmMessenger;
@@ -170,7 +185,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private int mBurnInXOffset;
private int mBurnInYOffset;
private ActivityIntentHelper mActivityIntentHelper;
- private int mLockScreenMode;
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
public KeyguardBottomAreaView(Context context) {
@@ -415,10 +429,11 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
}
private void updateWalletVisibility() {
- if (mDozing) {
+ if (mDozing || !mWalletEnabled) {
mWalletButton.setVisibility(GONE);
} else {
mWalletButton.setVisibility(VISIBLE);
+ mWalletButton.setOnClickListener(this::onWalletClick);
}
}
@@ -871,25 +886,63 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
return insets;
}
- private void setupWallet() {
- boolean inNewLayout = mLockScreenMode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
- boolean settingEnabled = Settings.Global.getInt(mContext.getContentResolver(),
- "controls_lockscreen", 0) == 1;
- if (!inNewLayout || !settingEnabled) {
- mWalletButton.setVisibility(View.GONE);
- return;
- }
-
- // TODO: add image
- // mWalletButton.setImageDrawable(list.get(0).loadIcon());
- updateWalletVisibility();
+ /** Set the falsing manager */
+ public void setFalsingManager(FalsingManager falsingManager) {
+ mFalsingManager = falsingManager;
}
/**
- * Optionally add controls when in the new lockscreen mode
+ * Initialize the wallet feature, only enabling if the feature is enabled within the platform.
*/
- public void onLockScreenModeChanged(int mode) {
- mLockScreenMode = mode;
- setupWallet();
+ public void initWallet(QuickAccessWalletClient client, Executor uiExecutor, boolean enabled) {
+ mQuickAccessWalletClient = client;
+ mWalletEnabled = enabled && client.isWalletFeatureAvailable();
+
+ if (mWalletEnabled) {
+ queryWalletCards(uiExecutor);
+ }
+ updateWalletVisibility();
+ }
+
+ private void queryWalletCards(Executor uiExecutor) {
+ GetWalletCardsRequest request =
+ new GetWalletCardsRequest(1 /* cardWidth */, 1 /* cardHeight */,
+ 1 /* iconSizePx */, 2 /* maxCards */);
+ mQuickAccessWalletClient.getWalletCards(uiExecutor, request, mCardRetriever);
+ }
+
+ private void onWalletClick(View v) {
+ // More coming here; need to inform the user about how to proceed
+ mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY);
+
+ if (mHasCard) {
+ Intent intent = new Intent(mContext, WalletActivity.class)
+ .setAction(Intent.ACTION_VIEW)
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+ } else {
+ if (mQuickAccessWalletClient.createWalletIntent() == null) {
+ Log.w(TAG, "Could not get intent of the wallet app.");
+ return;
+ }
+ mActivityStarter.postStartActivityDismissingKeyguard(
+ mQuickAccessWalletClient.createWalletIntent(), /* delay= */ 0);
+ }
+ }
+
+ private class WalletCardRetriever implements
+ QuickAccessWalletClient.OnWalletCardsRetrievedCallback {
+
+ @Override
+ public void onWalletCardsRetrieved(@NonNull GetWalletCardsResponse response) {
+ mHasCard = !response.getWalletCards().isEmpty();
+ updateWalletVisibility();
+ }
+
+ @Override
+ public void onWalletCardRetrievalError(@NonNull GetWalletCardsError error) {
+ mHasCard = false;
+ updateWalletVisibility();
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index f12bf7b53a0a..481b2db16964 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -25,8 +25,8 @@ import android.util.MathUtils;
import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcherListView;
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
index 8970a9a20931..5085e1cf9990 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
@@ -16,8 +16,6 @@
package com.android.systemui.statusbar.phone;
-import static com.android.keyguard.KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1;
-
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@@ -31,7 +29,7 @@ import android.view.View;
import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.Interpolators;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.keyguard.KeyguardIndication;
import java.util.LinkedList;
@@ -40,16 +38,12 @@ import java.util.LinkedList;
* A view to show hints on Keyguard ("Swipe up to unlock", "Tap again to open").
*/
public class KeyguardIndicationTextView extends TextView {
- private static final int FADE_OUT_MILLIS = 200;
- private static final int FADE_IN_MILLIS = 250;
private static final long MSG_DURATION_MILLIS = 600;
private long mNextAnimationTime = 0;
private boolean mAnimationsEnabled = true;
private LinkedList<CharSequence> mMessages = new LinkedList<>();
private LinkedList<KeyguardIndication> mKeyguardIndicationInfo = new LinkedList<>();
- private boolean mUseNewAnimations = false;
-
public KeyguardIndicationTextView(Context context) {
super(context);
}
@@ -67,10 +61,6 @@ public class KeyguardIndicationTextView extends TextView {
super(context, attrs, defStyleAttr, defStyleRes);
}
- public void setLockScreenMode(int lockScreenMode) {
- mUseNewAnimations = lockScreenMode == LOCK_SCREEN_MODE_LAYOUT_1;
- }
-
/**
* Changes the text with an animation and makes sure a single indication is shown long enough.
*/
@@ -148,15 +138,11 @@ public class KeyguardIndicationTextView extends TextView {
}
});
- if (mUseNewAnimations) {
- Animator yTranslate =
- ObjectAnimator.ofFloat(this, View.TRANSLATION_Y, 0, -getYTranslationPixels());
- yTranslate.setDuration(getFadeOutDuration());
- fadeOut.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
- animatorSet.playTogether(fadeOut, yTranslate);
- } else {
- animatorSet.play(fadeOut);
- }
+ Animator yTranslate =
+ ObjectAnimator.ofFloat(this, View.TRANSLATION_Y, 0, -getYTranslationPixels());
+ yTranslate.setDuration(getFadeOutDuration());
+ fadeOut.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
+ animatorSet.playTogether(fadeOut, yTranslate);
return animatorSet;
}
@@ -168,20 +154,16 @@ public class KeyguardIndicationTextView extends TextView {
fadeIn.setDuration(getFadeInDuration());
fadeIn.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
- if (mUseNewAnimations) {
- Animator yTranslate =
- ObjectAnimator.ofFloat(this, View.TRANSLATION_Y, getYTranslationPixels(), 0);
- yTranslate.setDuration(getYInDuration());
- yTranslate.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationCancel(Animator animation) {
- setTranslationY(0);
- }
- });
- animatorSet.playTogether(yTranslate, fadeIn);
- } else {
- animatorSet.play(fadeIn);
- }
+ Animator yTranslate =
+ ObjectAnimator.ofFloat(this, View.TRANSLATION_Y, getYTranslationPixels(), 0);
+ yTranslate.setDuration(getYInDuration());
+ yTranslate.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ setTranslationY(0);
+ }
+ });
+ animatorSet.playTogether(yTranslate, fadeIn);
return animatorSet;
}
@@ -193,26 +175,22 @@ public class KeyguardIndicationTextView extends TextView {
private long getFadeInDelay() {
if (!mAnimationsEnabled) return 0L;
- if (mUseNewAnimations) return 150L;
- return 0L;
+ return 150L;
}
private long getFadeInDuration() {
if (!mAnimationsEnabled) return 0L;
- if (mUseNewAnimations) return 317L;
- return FADE_IN_MILLIS;
+ return 317L;
}
private long getYInDuration() {
if (!mAnimationsEnabled) return 0L;
- if (mUseNewAnimations) return 600L;
- return 0L;
+ return 600L;
}
private long getFadeOutDuration() {
if (!mAnimationsEnabled) return 0L;
- if (mUseNewAnimations) return 167L;
- return FADE_OUT_MILLIS;
+ return 167L;
}
private void setNextAnimationTime(long time) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 3f8e9d372d82..06947376b9f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -44,8 +44,8 @@ import android.widget.TextView;
import com.android.settingslib.Utils;
import com.android.systemui.BatteryMeterView;
import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
import com.android.systemui.statusbar.policy.BatteryController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
index 5b7ffd2d4164..9021b74d1518 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
@@ -26,7 +26,7 @@ import android.util.TimeUtils;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
-import com.android.systemui.Interpolators;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CommandQueue.Callbacks;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 0df3347b8f89..cc4f901668ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -32,8 +32,8 @@ import android.util.SparseArray;
import android.view.ViewTreeObserver.OnPreDrawListener;
import com.android.internal.graphics.ColorUtils;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.KeyguardAffordanceView;
import java.lang.annotation.Retention;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index ac91b7050ae9..6b864c9c35df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -17,8 +17,8 @@ import androidx.collection.ArrayMap;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.util.ContrastColorUtil;
import com.android.settingslib.Utils;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.demomode.DemoMode;
import com.android.systemui.demomode.DemoModeController;
@@ -161,15 +161,14 @@ public class NotificationIconAreaController implements
/**
* Called by the Keyguard*ViewController whose view contains the aod icons.
*/
- public void setupAodIcons(@NonNull NotificationIconContainer aodIcons,
- int lockScreenMode) {
+ public void setupAodIcons(@NonNull NotificationIconContainer aodIcons) {
boolean changed = mAodIcons != null;
if (changed) {
mAodIcons.setAnimationsEnabled(false);
mAodIcons.removeAllViews();
}
mAodIcons = aodIcons;
- mAodIcons.setOnLockScreen(true, lockScreenMode);
+ mAodIcons.setOnLockScreen(true);
updateAodIconsVisibility(false /* animate */);
updateAnimations();
if (changed) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 25de551d2699..c09c48540901 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -35,10 +35,9 @@ import android.view.animation.Interpolator;
import androidx.collection.ArrayMap;
import com.android.internal.statusbar.StatusBarIcon;
-import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.settingslib.Utils;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.AlphaOptimizedFrameLayout;
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.notification.stack.AnimationFilter;
@@ -151,7 +150,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
private float mActualPaddingStart = NO_VALUE;
private boolean mDozing;
private boolean mOnLockScreen;
- private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
private boolean mInNotificationIconShelf;
private boolean mChangingViewPositions;
private int mAddAnimationStartIndex = -1;
@@ -464,33 +462,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
mFirstVisibleIconState = mIconStates.get(getChildAt(0));
}
- boolean center = mOnLockScreen
- && mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
- if (center && translationX < getLayoutEnd()) {
- float initialTranslation =
- mFirstVisibleIconState == null ? 0 : mFirstVisibleIconState.xTranslation;
-
- float contentWidth = 0;
- if (mLastVisibleIconState != null) {
- contentWidth = mLastVisibleIconState.xTranslation + mIconSize;
- contentWidth = Math.min(getWidth(), contentWidth) - initialTranslation;
- }
- float availableSpace = getLayoutEnd() - getActualPaddingStart();
- float delta = (availableSpace - contentWidth) / 2;
-
- if (firstOverflowIndex != -1) {
- // If we have an overflow, only count those half for centering because the dots
- // don't have a lot of visual weight.
- float deltaIgnoringOverflow = (getLayoutEnd() - mVisualOverflowStart) / 2;
- delta = (deltaIgnoringOverflow + delta) / 2;
- }
- for (int i = 0; i < childCount; i++) {
- View view = getChildAt(i);
- IconState iconState = mIconStates.get(view);
- iconState.xTranslation += delta;
- }
- }
-
if (isLayoutRtl()) {
for (int i = 0; i < childCount; i++) {
View view = getChildAt(i);
@@ -698,9 +669,8 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
* Set whether the device is on the lockscreen and which lockscreen mode the device is
* configured to. Depending on these values, the layout of the AOD icons change.
*/
- public void setOnLockScreen(boolean onLockScreen, int lockScreenMode) {
+ public void setOnLockScreen(boolean onLockScreen) {
mOnLockScreen = onLockScreen;
- mLockScreenMode = lockScreenMode;
}
public void setInNotificationIconShelf(boolean inShelf) {
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 25c13276b14b..6a35293def76 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -53,6 +53,7 @@ import android.os.Bundle;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.UserManager;
+import android.service.quickaccesswallet.QuickAccessWalletClient;
import android.util.Log;
import android.util.MathUtils;
import android.view.DisplayCutout;
@@ -76,7 +77,6 @@ import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.LatencyTracker;
-import com.android.keyguard.KeyguardClockSwitchController;
import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardStatusViewController;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -87,8 +87,9 @@ import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
import com.android.systemui.DejankUtils;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.ActivityLaunchAnimator;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.classifier.FalsingCollector;
@@ -100,7 +101,6 @@ import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
import com.android.systemui.media.MediaDataManager;
import com.android.systemui.media.MediaHierarchyManager;
import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.animation.ActivityLaunchAnimator;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -155,6 +155,7 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -363,6 +364,7 @@ public class NotificationPanelViewController extends PanelViewController {
private float mDownX;
private float mDownY;
private int mDisplayCutoutTopInset = 0; // in pixels
+ private int mSplitShadeNotificationsTopPadding;
private final KeyguardClockPositionAlgorithm
mClockPositionAlgorithm =
@@ -517,6 +519,9 @@ public class NotificationPanelViewController extends PanelViewController {
private int mOldLayoutDirection;
private NotificationShelfController mNotificationShelfController;
+ private final QuickAccessWalletClient mQuickAccessWalletClient;
+ private final Executor mUiExecutor;
+
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
private View.AccessibilityDelegate mAccessibilityDelegate = new View.AccessibilityDelegate() {
@@ -578,7 +583,9 @@ public class NotificationPanelViewController extends PanelViewController {
NotificationShadeDepthController notificationShadeDepthController,
AmbientState ambientState,
LockIconViewController lockIconViewController,
- FeatureFlags featureFlags) {
+ FeatureFlags featureFlags,
+ QuickAccessWalletClient quickAccessWalletClient,
+ @Main Executor uiExecutor) {
super(view, falsingManager, dozeLog, keyguardStateController,
(SysuiStatusBarStateController) statusBarStateController, vibratorHelper,
statusBarKeyguardViewManager, latencyTracker, flingAnimationUtilsBuilder.get(),
@@ -624,6 +631,8 @@ public class NotificationPanelViewController extends PanelViewController {
mScrimController = scrimController;
mUserManager = userManager;
mMediaDataManager = mediaDataManager;
+ mQuickAccessWalletClient = quickAccessWalletClient;
+ mUiExecutor = uiExecutor;
pulseExpansionHandler.setPulseExpandAbortListener(() -> {
if (mQs != null) {
mQs.animateHeaderSlidingOut();
@@ -798,11 +807,6 @@ public class NotificationPanelViewController extends PanelViewController {
statusBarViewComponent.getKeyguardStatusBarViewController();
mKeyguarStatusBarViewController.init();
- // Re-associate the clock container with the keyguard clock switch.
- KeyguardClockSwitchController keyguardClockSwitchController =
- statusViewComponent.getKeyguardClockSwitchController();
- keyguardClockSwitchController.setBigClockContainer(mBigClockContainer);
-
if (mKeyguardUserSwitcherController != null) {
// Try to close the switcher so that callbacks are triggered if necessary.
// Otherwise, NPV can get into a state where some of the views are still hidden
@@ -847,6 +851,8 @@ public class NotificationPanelViewController extends PanelViewController {
}
public void updateResources() {
+ mSplitShadeNotificationsTopPadding =
+ mResources.getDimensionPixelSize(R.dimen.notifications_top_padding_split_shade);
int qsWidth = mResources.getDimensionPixelSize(R.dimen.qs_panel_width);
int panelWidth = mResources.getDimensionPixelSize(R.dimen.notification_panel_width);
mShouldUseSplitNotificationShade =
@@ -978,6 +984,9 @@ public class NotificationPanelViewController extends PanelViewController {
mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper);
mKeyguardBottomArea.setStatusBar(mStatusBar);
mKeyguardBottomArea.setUserSetupComplete(mUserSetupComplete);
+ mKeyguardBottomArea.setFalsingManager(mFalsingManager);
+ mKeyguardBottomArea.initWallet(mQuickAccessWalletClient, mUiExecutor,
+ mFeatureFlags.isQuickAccessWalletEnabled());
}
private void updateMaxDisplayedNotifications(boolean recompute) {
@@ -2019,10 +2028,9 @@ public class NotificationPanelViewController extends PanelViewController {
}
}
- private float calculateQsTopPadding() {
- // in split shade mode we want notifications to be directly below status bar
+ private float calculateNotificationsTopPadding() {
if (mShouldUseSplitNotificationShade && !mKeyguardShowing) {
- return 0f;
+ return mSplitShadeNotificationsTopPadding;
}
if (mKeyguardShowing && (mQsExpandImmediate
|| mIsExpanding && mQsExpandedWhenExpandingStarted)) {
@@ -2076,7 +2084,8 @@ public class NotificationPanelViewController extends PanelViewController {
protected void requestScrollerTopPaddingUpdate(boolean animate) {
- mNotificationStackScrollLayoutController.updateTopPadding(calculateQsTopPadding(), animate);
+ mNotificationStackScrollLayoutController.updateTopPadding(
+ calculateNotificationsTopPadding(), animate);
if (mKeyguardShowing && mKeyguardBypassController.getBypassEnabled()) {
// update the position of the header
updateQsExpansion();
@@ -4056,7 +4065,8 @@ public class NotificationPanelViewController extends PanelViewController {
calculatePanelHeightShade(), p);
p.setColor(Color.MAGENTA);
canvas.drawLine(
- 0, calculateQsTopPadding(), mView.getWidth(), calculateQsTopPadding(), p);
+ 0, calculateNotificationsTopPadding(), mView.getWidth(),
+ calculateNotificationsTopPadding(), p);
p.setColor(Color.CYAN);
canvas.drawLine(0, mClockPositionResult.stackScrollerPadding, mView.getWidth(),
mNotificationStackScrollLayoutController.getTopPadding(), p);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index 936e28960f47..a80e270f38c6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -47,8 +47,8 @@ import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.LatencyTracker;
import com.android.systemui.DejankUtils;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.plugins.FalsingManager;
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 adde4d83a31a..58488ef8ffd2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -497,7 +497,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
return;
}
shiftNotificationsScrim(qsPanelBottomY);
- updateNotificationsScrimAlpha(qsPanelBottomY);
+ updateNotificationsScrimAlpha(expansionFraction, qsPanelBottomY);
if (mQsExpansion != expansionFraction) {
mQsExpansion = expansionFraction;
boolean relevantState = (mState == ScrimState.SHADE_LOCKED
@@ -519,14 +519,14 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
}
}
- private void updateNotificationsScrimAlpha(int qsPanelBottomY) {
+ private void updateNotificationsScrimAlpha(float qsExpansion, int qsPanelBottomY) {
float newAlpha = 0;
if (qsPanelBottomY > 0) {
float interpolator = 0;
if (mState == ScrimState.UNLOCKED || mState == ScrimState.SHADE_LOCKED) {
interpolator = getInterpolatedFraction();
} else {
- interpolator = mQsExpansion;
+ interpolator = qsExpansion;
}
newAlpha = MathUtils.lerp(0, 1, interpolator);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
index 1130b6de2544..9cefded72365 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
@@ -28,7 +28,7 @@ import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import com.android.keyguard.AlphaOptimizedImageButton;
-import com.android.systemui.Interpolators;
+import com.android.systemui.animation.Interpolators;
public class SettingsButton extends AlphaOptimizedImageButton {
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 19ece624f216..d386ebde26bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -148,6 +148,7 @@ import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
+import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.camera.CameraIntents;
@@ -173,7 +174,6 @@ import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.OverlayPlugin;
import com.android.systemui.plugins.PluginDependencyProvider;
import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.animation.ActivityLaunchAnimator;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -1372,7 +1372,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private void setUpPresenter() {
// Set up the initial notification state.
- mActivityLaunchAnimator = new ActivityLaunchAnimator();
+ mActivityLaunchAnimator = new ActivityLaunchAnimator(mContext);
mNotificationAnimationProvider = new NotificationLaunchAnimatorControllerProvider(
mNotificationShadeWindowViewController,
mNotificationPanelViewController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
index d45f64fd83b0..2f52158c40db 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
@@ -1,6 +1,6 @@
package com.android.systemui.statusbar.phone
-import com.android.systemui.plugins.animation.ActivityLaunchAnimator
+import com.android.systemui.animation.ActivityLaunchAnimator
/**
* A [ActivityLaunchAnimator.Controller] that takes care of collapsing the status bar at the right
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index 2e918da0d560..3404528be447 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -45,12 +45,12 @@ import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.EventLogTags;
+import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.animation.ActivityLaunchAnimator;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java
index 0649478a42aa..4dd63be47735 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java
@@ -25,8 +25,8 @@ import android.view.View;
import androidx.core.graphics.ColorUtils;
import com.android.keyguard.KeyguardConstants;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.qs.tiles.UserDetailItemView;
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
index 25e908450808..e2c52f9a3961 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java
@@ -40,8 +40,8 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.KeyguardVisibilityHelper;
import com.android.keyguard.dagger.KeyguardUserSwitcherScope;
import com.android.settingslib.drawable.CircleFramedDrawable;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherListView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherListView.java
index a815adfc9c9a..20b66f03192e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherListView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherListView.java
@@ -25,7 +25,7 @@ import com.android.keyguard.AlphaOptimizedLinearLayout;
import com.android.keyguard.KeyguardConstants;
import com.android.settingslib.animation.AppearAnimationUtils;
import com.android.settingslib.animation.DisappearAnimationUtils;
-import com.android.systemui.Interpolators;
+import com.android.systemui.animation.Interpolators;
/**
* The container for the user switcher on Keyguard.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 6843eb509b86..f2a0e3786885 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -80,8 +80,8 @@ import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.ContrastColorUtil;
import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt b/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt
index 9638ac1096f7..0c9b48ecd844 100644
--- a/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt
@@ -19,8 +19,7 @@ package com.android.systemui.util.animation
import android.animation.ValueAnimator
import android.graphics.PointF
import android.util.MathUtils
-import com.android.internal.R.attr.width
-import com.android.systemui.Interpolators
+import com.android.systemui.animation.Interpolators
/**
* The fraction after which we start fading in when going from a gone widget to a visible one
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index a8a3d79c67cf..8459b7b6ed05 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -99,9 +99,9 @@ import android.widget.Toast;
import com.android.internal.graphics.drawable.BackgroundBlurDrawable;
import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
import com.android.systemui.Prefs;
import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.VolumeDialog;
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
index c1835db9ab0c..f884687daad4 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
@@ -94,17 +94,15 @@ public class WalletActivity extends LifecycleActivity {
mHandler,
mUserTracker,
mKeyguardStateController);
- // Clicking the wallet button will open the wallet app if the device is unlocked; bring up
- // the security bouncer otherwise.
- walletView.getWalletButton().setOnClickListener(
- v -> {
- if (mKeyguardStateController.isUnlocked()) {
- mActivityStarter.startActivity(
- mQuickAccessWalletClient.createWalletIntent(), true);
- } else {
- mKeyguardDismissUtil.executeWhenUnlocked(() -> false, false);
- }
- });
+
+ walletView.getAppButton().setOnClickListener(
+ v -> mActivityStarter.startActivity(
+ mQuickAccessWalletClient.createWalletIntent(), true));
+ // Click the action button to re-render the screen when the device is unlocked.
+ if (!mKeyguardStateController.isUnlocked()) {
+ walletView.getActionButton().setOnClickListener(
+ v -> mKeyguardDismissUtil.executeWhenUnlocked(() -> false, false));
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
index a3793945aedf..a3c26998e2c0 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
@@ -54,7 +54,10 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
private final WalletCardCarousel mCardCarousel;
private final ImageView mIcon;
private final TextView mCardLabel;
- private final Button mWalletButton;
+ // Displays at the bottom of the screen, allow user to enter the default wallet app.
+ private final Button mAppButton;
+ // Displays underneath the carousel, allow user to unlock device, verify card, etc.
+ private final Button mActionButton;
private final Interpolator mInInterpolator;
private final Interpolator mOutInterpolator;
private final float mAnimationTranslationX;
@@ -75,7 +78,8 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
mCardCarousel.setCardScrollListener(this);
mIcon = requireViewById(R.id.icon);
mCardLabel = requireViewById(R.id.label);
- mWalletButton = requireViewById(R.id.wallet_button);
+ mAppButton = requireViewById(R.id.wallet_app_button);
+ mActionButton = requireViewById(R.id.wallet_action_button);
mErrorView = requireViewById(R.id.error_view);
mEmptyStateView = requireViewById(R.id.wallet_empty_state);
mInInterpolator =
@@ -101,15 +105,6 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
public void onCardScroll(WalletCardViewInfo centerCard, WalletCardViewInfo nextCard,
float percentDistanceFromCenter) {
CharSequence centerCardText = centerCard.getLabel();
- Drawable icon = centerCard.getIcon();
- if (icon != null) {
- Drawable drawable = resizeDrawable(getResources(), icon);
- drawable.setTint(mContext.getColor(R.color.GM2_blue_600));
- mIcon.setImageDrawable(drawable);
- mIcon.setVisibility(VISIBLE);
- } else {
- mIcon.setVisibility(INVISIBLE);
- }
if (!TextUtils.equals(mCenterCardText, centerCardText)) {
mCenterCardText = centerCardText;
mCardLabel.setText(centerCardText);
@@ -122,16 +117,21 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
}
}
+ /**
+ * Render and show card carousel view.
+ *
+ * <p>This is called only when {@param data} is not empty.</p>
+ *
+ * @param data a list of wallet cards information.
+ * @param selectedIndex index of the current selected card
+ * @param isDeviceLocked indicates whether the device is locked.
+ */
void showCardCarousel(
List<WalletCardViewInfo> data, int selectedIndex, boolean isDeviceLocked) {
boolean shouldAnimate = mCardCarousel.setData(data, selectedIndex);
mCardCarouselContainer.setVisibility(VISIBLE);
mErrorView.setVisibility(GONE);
- if (isDeviceLocked) {
- mWalletButton.setText(R.string.wallet_button_label_device_locked);
- } else {
- mWalletButton.setText(R.string.wallet_button_label_device_unlocked);
- }
+ renderHeaderIconAndActionButton(data.get(0), isDeviceLocked);
if (shouldAnimate) {
// If the empty state is visible, animate it away and delay the card carousel animation
int emptyStateAnimDelay = 0;
@@ -216,8 +216,12 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
return mCardCarousel;
}
- Button getWalletButton() {
- return mWalletButton;
+ Button getAppButton() {
+ return mAppButton;
+ }
+
+ Button getActionButton() {
+ return mActionButton;
}
@VisibleForTesting
@@ -235,7 +239,37 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
return mCardCarouselContainer;
}
- private static Drawable resizeDrawable(Resources resources, Drawable drawable) {
+ private void renderHeaderIconAndActionButton(WalletCardViewInfo walletCard, boolean isLocked) {
+ Drawable icon = resizeDrawable(getResources(), walletCard.getIcon());
+ renderHeaderIcon(icon, isLocked);
+ if (isLocked) {
+ mActionButton.setVisibility(VISIBLE);
+ mActionButton.setText(R.string.wallet_action_button_label_unlock);
+ } else {
+ mActionButton.setVisibility(GONE);
+ }
+ }
+
+ private void renderHeaderIcon(@Nullable Drawable icon, boolean isLocked) {
+ if (icon == null) {
+ mIcon.setVisibility(INVISIBLE);
+ return;
+ }
+ icon.setTint(mContext.getColor(isLocked ? R.color.GM2_grey_800 : R.color.GM2_blue_600));
+ mIcon.setImageDrawable(icon);
+ mIcon.setVisibility(VISIBLE);
+ mIcon.setBackground(
+ mContext.getDrawable(
+ isLocked
+ ? R.drawable.circle_wallet_secondary_56dp
+ : R.drawable.circle_wallet_primary_56dp));
+ }
+
+ @Nullable
+ private static Drawable resizeDrawable(Resources resources, @Nullable Drawable drawable) {
+ if (drawable == null) {
+ return null;
+ }
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
return new BitmapDrawable(resources, Bitmap.createScaledBitmap(
bitmap, CONTACTLESS_ICON_SIZE, CONTACTLESS_ICON_SIZE, true));
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
index afeda967c8c1..55b80dd69b6a 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
@@ -38,7 +38,6 @@ 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;
@@ -85,16 +84,13 @@ 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.HashMap;
import java.util.List;
import java.util.Optional;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.IntConsumer;
-import java.util.function.Supplier;
/**
* The SysUi side bubbles manager which communicate with other SysUi components.
@@ -252,6 +248,13 @@ public class BubblesManager implements Dumpable {
mSysuiProxy = new Bubbles.SysuiProxy() {
@Override
+ public void isNotificationShadeExpand(Consumer<Boolean> callback) {
+ sysuiMainExecutor.execute(() -> {
+ callback.accept(mNotificationShadeWindowController.getPanelExpanded());
+ });
+ }
+
+ @Override
public void getPendingOrActiveEntry(String key, Consumer<BubbleEntry> callback) {
sysuiMainExecutor.execute(() -> {
NotificationEntry entry =
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
index 45b0b59cd1d9..3fc3d89461ae 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
@@ -186,14 +186,15 @@ public abstract class WMShellBaseModule {
WindowManager windowManager,
WindowManagerShellWrapper windowManagerShellWrapper,
LauncherApps launcherApps,
+ TaskStackListenerImpl taskStackListener,
UiEventLogger uiEventLogger,
ShellTaskOrganizer organizer,
@ShellMainThread ShellExecutor mainExecutor,
@ShellMainThread Handler mainHandler) {
return Optional.of(BubbleController.create(context, null /* synchronizer */,
floatingContentCoordinator, statusBarService, windowManager,
- windowManagerShellWrapper, launcherApps, uiEventLogger, organizer,
- mainExecutor, mainHandler));
+ windowManagerShellWrapper, launcherApps, taskStackListener,
+ uiEventLogger, organizer, mainExecutor, mainHandler));
}
//
@@ -334,10 +335,12 @@ public abstract class WMShellBaseModule {
SyncTransactionQueue syncQueue, Context context,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
@ShellMainThread ShellExecutor mainExecutor,
- DisplayImeController displayImeController) {
+ DisplayImeController displayImeController, Transitions transitions,
+ TransactionPool transactionPool) {
if (ActivityTaskManager.supportsSplitScreenMultiWindow(context)) {
return Optional.of(new SplitScreenController(shellTaskOrganizer, syncQueue, context,
- rootTaskDisplayAreaOrganizer, mainExecutor, displayImeController));
+ rootTaskDisplayAreaOrganizer, mainExecutor, displayImeController, transitions,
+ transactionPool));
} else {
return Optional.empty();
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index 70a7b7a5acbc..9017dd244fb4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -18,29 +18,36 @@ package com.android.keyguard;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
+import android.content.Context;
import android.content.res.Resources;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
+import android.util.AttributeSet;
import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
+import android.widget.RelativeLayout;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.keyguard.clock.ClockManager;
+import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.BcSmartspaceDataPlugin;
import com.android.systemui.plugins.ClockPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.NotificationIconContainer;
+import com.android.systemui.statusbar.policy.BatteryController;
import org.junit.Before;
import org.junit.Test;
@@ -50,6 +57,8 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.verification.VerificationMode;
+import java.util.concurrent.Executor;
+
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
@@ -78,6 +87,18 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
ContentResolver mContentResolver;
@Mock
BroadcastDispatcher mBroadcastDispatcher;
+ @Mock
+ private PluginManager mPluginManager;
+ @Mock
+ private FeatureFlags mFeatureFlags;
+ @Mock
+ private Executor mExecutor;
+ @Mock
+ private AnimatableClockView mClockView;
+ @Mock
+ private AnimatableClockView mLargeClockView;
+ @Mock
+ BatteryController mBatteryController;
private KeyguardClockSwitchController mController;
@@ -85,8 +106,16 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
public void setup() {
MockitoAnnotations.initMocks(this);
- when(mView.findViewById(com.android.systemui.R.id.left_aligned_notification_icon_container))
+ when(mView.findViewById(R.id.left_aligned_notification_icon_container))
.thenReturn(mNotificationIcons);
+ when(mView.getContext()).thenReturn(getContext());
+
+ when(mView.findViewById(R.id.animatable_clock_view)).thenReturn(mClockView);
+ when(mView.findViewById(R.id.animatable_clock_view_large)).thenReturn(mLargeClockView);
+ when(mClockView.getContext()).thenReturn(getContext());
+ when(mLargeClockView.getContext()).thenReturn(getContext());
+
+ when(mFeatureFlags.isSmartspaceEnabled()).thenReturn(true);
when(mView.isAttachedToWindow()).thenReturn(true);
when(mResources.getString(anyInt())).thenReturn("h:mm");
mController = new KeyguardClockSwitchController(
@@ -98,7 +127,11 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
mKeyguardSliceViewController,
mNotificationIconAreaController,
mContentResolver,
- mBroadcastDispatcher);
+ mBroadcastDispatcher,
+ mPluginManager,
+ mFeatureFlags,
+ mExecutor,
+ mBatteryController);
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
when(mColorExtractor.getColors(anyInt())).thenReturn(mGradientColors);
@@ -144,51 +177,74 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
listenerArgumentCaptor.getValue().onViewDetachedFromWindow(mView);
- verify(mStatusBarStateController).removeCallback(
- any(StatusBarStateController.StateListener.class));
verify(mColorExtractor).removeOnColorsChangedListener(
any(ColorExtractor.OnColorsChangedListener.class));
}
@Test
- public void testBigClockPassesStatusBarState() {
- ViewGroup testView = new FrameLayout(mContext);
+ public void testPluginPassesStatusBarState() {
+ ArgumentCaptor<ClockManager.ClockChangedListener> listenerArgumentCaptor =
+ ArgumentCaptor.forClass(ClockManager.ClockChangedListener.class);
mController.init();
- when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
- mController.setBigClockContainer(testView);
- verify(mView).setBigClockContainer(testView, StatusBarState.SHADE);
+ verify(mClockManager).addOnClockChangedListener(listenerArgumentCaptor.capture());
+
+ listenerArgumentCaptor.getValue().onClockChanged(mClockPlugin);
+ verify(mView).setClockPlugin(mClockPlugin, StatusBarState.SHADE);
+ }
+ @Test
+ public void testSmartspacePluginConnectedRemovesKeyguardStatusArea() {
+ mController.init();
- when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
- mController.setBigClockContainer(testView);
- verify(mView).setBigClockContainer(testView, StatusBarState.KEYGUARD);
+ View statusArea = mock(View.class);
+ when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(statusArea);
+ View nic = mock(View.class);
+ when(mView.findViewById(R.id.left_aligned_notification_icon_container)).thenReturn(nic);
+ when(nic.getLayoutParams()).thenReturn(mock(RelativeLayout.LayoutParams.class));
- when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE_LOCKED);
- mController.setBigClockContainer(testView);
- verify(mView).setBigClockContainer(testView, StatusBarState.SHADE_LOCKED);
+ BcSmartspaceDataPlugin plugin = mock(BcSmartspaceDataPlugin.class);
+ TestView view = mock(TestView.class);
+ when(plugin.getView(any())).thenReturn(view);
+
+ mController.mPluginListener.onPluginConnected(plugin, mContext);
+ verify(statusArea).setVisibility(View.GONE);
}
@Test
- public void testPluginPassesStatusBarState() {
- ArgumentCaptor<ClockManager.ClockChangedListener> listenerArgumentCaptor =
- ArgumentCaptor.forClass(ClockManager.ClockChangedListener.class);
-
+ public void testSmartspacePluginDisconnectedShowsKeyguardStatusArea() {
mController.init();
- verify(mClockManager).addOnClockChangedListener(listenerArgumentCaptor.capture());
- listenerArgumentCaptor.getValue().onClockChanged(mClockPlugin);
- verify(mView).setClockPlugin(mClockPlugin, StatusBarState.SHADE);
+ View statusArea = mock(View.class);
+ when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(statusArea);
+
+ View nic = mock(View.class);
+ when(mView.findViewById(R.id.left_aligned_notification_icon_container)).thenReturn(nic);
+ when(nic.getLayoutParams()).thenReturn(mock(RelativeLayout.LayoutParams.class));
+
+ BcSmartspaceDataPlugin plugin = mock(BcSmartspaceDataPlugin.class);
+ TestView view = mock(TestView.class);
+ when(plugin.getView(any())).thenReturn(view);
+
+ mController.mPluginListener.onPluginConnected(plugin, mContext);
+ mController.mPluginListener.onPluginDisconnected(plugin);
+ verify(statusArea).setVisibility(View.VISIBLE);
}
private void verifyAttachment(VerificationMode times) {
verify(mClockManager, times).addOnClockChangedListener(
any(ClockManager.ClockChangedListener.class));
- verify(mStatusBarStateController, times).addCallback(
- any(StatusBarStateController.StateListener.class));
verify(mColorExtractor, times).addOnColorsChangedListener(
any(ColorExtractor.OnColorsChangedListener.class));
verify(mView, times).updateColors(mGradientColors);
}
+
+ private static class TestView extends View implements BcSmartspaceDataPlugin.SmartspaceView {
+ TestView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public void registerDataProvider(BcSmartspaceDataPlugin plugin) { }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index e7930795c7f8..10ed1d75a533 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -21,9 +21,7 @@ import static android.view.View.VISIBLE;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -33,7 +31,6 @@ import android.graphics.Paint.Style;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
-import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -48,8 +45,6 @@ import com.android.systemui.statusbar.StatusBarState;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
@@ -59,14 +54,13 @@ import org.mockito.MockitoAnnotations;
// the keyguard_clcok_switch layout is inflated.
@RunWithLooper(setAsMainLooper = true)
public class KeyguardClockSwitchTest extends SysuiTestCase {
- private FrameLayout mClockContainer;
- private FrameLayout mBigClockContainer;
+ private FrameLayout mClockFrame;
+ private FrameLayout mLargeClockFrame;
private TextClock mBigClock;
- @Mock
- TextClock mClockView;
+ private AnimatableClockView mClockView;
+ private AnimatableClockView mLargeClockView;
View mMockKeyguardSliceView;
- @InjectMocks
KeyguardClockSwitch mKeyguardClockSwitch;
@Before
@@ -95,11 +89,12 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
});
mKeyguardClockSwitch =
(KeyguardClockSwitch) layoutInflater.inflate(R.layout.keyguard_clock_switch, null);
- mClockContainer = mKeyguardClockSwitch.findViewById(R.id.clock_view);
- mBigClockContainer = new FrameLayout(getContext());
+ mClockFrame = mKeyguardClockSwitch.findViewById(R.id.lockscreen_clock_view);
+ mClockView = mKeyguardClockSwitch.findViewById(R.id.animatable_clock_view);
+ mLargeClockFrame = mKeyguardClockSwitch.findViewById(R.id.lockscreen_clock_view_large);
+ mLargeClockView = mKeyguardClockSwitch.findViewById(R.id.animatable_clock_view_large);
mBigClock = new TextClock(getContext());
MockitoAnnotations.initMocks(this);
- when(mClockView.getPaint()).thenReturn(mock(TextPaint.class));
}
@Test
@@ -110,33 +105,28 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
- verify(mClockView).setVisibility(GONE);
- assertThat(plugin.getView().getParent()).isEqualTo(mClockContainer);
+ assertThat(mClockView.getVisibility()).isEqualTo(GONE);
+ assertThat(plugin.getView().getParent()).isEqualTo(mClockFrame);
}
@Test
public void onPluginConnected_showPluginBigClock() {
- // GIVEN that the container for the big clock has visibility GONE
- mBigClockContainer.setVisibility(GONE);
- mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
- // AND the plugin returns a view for the big clock
+ // GIVEN the plugin returns a view for the big clock
ClockPlugin plugin = mock(ClockPlugin.class);
when(plugin.getBigClockView()).thenReturn(mBigClock);
- // AND in the keyguard state
- mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
// WHEN the plugin is connected
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
// THEN the big clock container is visible and it is the parent of the
// big clock view.
- assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
- assertThat(mBigClock.getParent()).isEqualTo(mBigClockContainer);
+ assertThat(mLargeClockView.getVisibility()).isEqualTo(View.GONE);
+ assertThat(mBigClock.getParent()).isEqualTo(mLargeClockFrame);
}
@Test
public void onPluginConnected_nullView() {
ClockPlugin plugin = mock(ClockPlugin.class);
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
- verify(mClockView, never()).setVisibility(GONE);
+ assertThat(mClockView.getVisibility()).isEqualTo(VISIBLE);
}
@Test
@@ -150,7 +140,7 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
when(plugin2.getView()).thenReturn(new TextClock(getContext()));
mKeyguardClockSwitch.setClockPlugin(plugin2, StatusBarState.KEYGUARD);
// THEN only the view from the second plugin should be a child of KeyguardClockSwitch.
- assertThat(plugin2.getView().getParent()).isEqualTo(mClockContainer);
+ assertThat(plugin2.getView().getParent()).isEqualTo(mClockFrame);
assertThat(plugin1.getView().getParent()).isNull();
}
@@ -170,33 +160,28 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
ClockPlugin plugin = mock(ClockPlugin.class);
TextClock pluginView = new TextClock(getContext());
when(plugin.getView()).thenReturn(pluginView);
- mClockView.setVisibility(GONE);
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
+ assertThat(mClockView.getVisibility()).isEqualTo(GONE);
+
mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
+ assertThat(mClockView.getVisibility()).isEqualTo(VISIBLE);
- verify(mClockView).setVisibility(VISIBLE);
assertThat(plugin.getView().getParent()).isNull();
}
@Test
public void onPluginDisconnected_hidePluginBigClock() {
- // GIVEN that the big clock container is visible
- FrameLayout bigClockContainer = new FrameLayout(getContext());
- bigClockContainer.setVisibility(VISIBLE);
- mKeyguardClockSwitch.setBigClockContainer(bigClockContainer, StatusBarState.KEYGUARD);
- // AND the plugin returns a view for the big clock
+ // GIVEN the plugin returns a view for the big clock
ClockPlugin plugin = mock(ClockPlugin.class);
TextClock pluginView = new TextClock(getContext());
when(plugin.getBigClockView()).thenReturn(pluginView);
- // AND in the keyguard state
- mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
// WHEN the plugin is connected and then disconnected
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
// THEN the big lock container is GONE and the big clock view doesn't have
// a parent.
- assertThat(bigClockContainer.getVisibility()).isEqualTo(GONE);
+ assertThat(mLargeClockView.getVisibility()).isEqualTo(VISIBLE);
assertThat(pluginView.getParent()).isNull();
}
@@ -205,7 +190,7 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
ClockPlugin plugin = mock(ClockPlugin.class);
mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
- verify(mClockView, never()).setVisibility(GONE);
+ assertThat(mClockView.getVisibility()).isEqualTo(VISIBLE);
}
@Test
@@ -220,7 +205,7 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
// WHEN the second plugin is disconnected
mKeyguardClockSwitch.setClockPlugin(null, StatusBarState.KEYGUARD);
// THEN the default clock should be shown.
- verify(mClockView).setVisibility(VISIBLE);
+ assertThat(mClockView.getVisibility()).isEqualTo(VISIBLE);
assertThat(plugin1.getView().getParent()).isNull();
assertThat(plugin2.getView().getParent()).isNull();
}
@@ -238,13 +223,6 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
}
@Test
- public void setTextColor_defaultClockSetTextColor() {
- mKeyguardClockSwitch.setTextColor(Color.YELLOW);
-
- verify(mClockView).setTextColor(Color.YELLOW);
- }
-
- @Test
public void setTextColor_pluginClockSetTextColor() {
ClockPlugin plugin = mock(ClockPlugin.class);
TextClock pluginView = new TextClock(getContext());
@@ -256,16 +234,6 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
verify(plugin).setTextColor(Color.WHITE);
}
- @Test
- public void setStyle_defaultClockSetStyle() {
- TextPaint paint = mock(TextPaint.class);
- Style style = mock(Style.class);
- doReturn(paint).when(mClockView).getPaint();
-
- mKeyguardClockSwitch.setStyle(style);
-
- verify(paint).setStyle(style);
- }
@Test
public void setStyle_pluginClockSetStyle() {
@@ -279,98 +247,4 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
verify(plugin).setStyle(style);
}
-
- @Test
- public void onStateChanged_GoneInShade() {
- // GIVEN that the big clock container is visible
- mBigClockContainer.setVisibility(View.VISIBLE);
- mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
- // WHEN transitioned to SHADE state
- mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.SHADE);
- // THEN the container is gone.
- assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.GONE);
- }
-
- @Test
- public void onStateChanged_VisibleInKeyguard() {
- // GIVEN that the big clock container is gone
- mBigClockContainer.setVisibility(View.GONE);
- mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
- // AND GIVEN that a plugin is active.
- ClockPlugin plugin = mock(ClockPlugin.class);
- when(plugin.getBigClockView()).thenReturn(mBigClock);
- mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
- // WHEN transitioned to KEYGUARD state
- mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
- // THEN the container is visible.
- assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
- }
-
- @Test
- public void setBigClockContainer_visible() {
- // GIVEN that the big clock container is visible
- mBigClockContainer.setVisibility(View.VISIBLE);
- // AND GIVEN that a plugin is active.
- ClockPlugin plugin = mock(ClockPlugin.class);
- when(plugin.getBigClockView()).thenReturn(mBigClock);
- mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
- // AND in the keyguard state
- mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
- // WHEN the container is associated with the clock switch
- mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
- // THEN the container remains visible.
- assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
- }
-
- @Test
- public void setBigClockContainer_gone() {
- // GIVEN that the big clock container is gone
- mBigClockContainer.setVisibility(View.GONE);
- // AND GIVEN that a plugin is active.
- ClockPlugin plugin = mock(ClockPlugin.class);
- when(plugin.getBigClockView()).thenReturn(mBigClock);
- mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
- // AND in the keyguard state
- mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
- // WHEN the container is associated with the clock switch
- mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
- // THEN the container is made visible.
- assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
- }
-
- @Test
- public void setKeyguardHidingBigClock_gone() {
- // GIVEN that the container for the big clock has visibility GONE
- mBigClockContainer.setVisibility(GONE);
- mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
- // AND the plugin returns a view for the big clock
- ClockPlugin plugin = mock(ClockPlugin.class);
- when(plugin.getBigClockView()).thenReturn(mBigClock);
- // AND in the keyguard state
- mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
- // WHEN the plugin is connected
- mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
- // WHEN the container set hiding clock as true
- mKeyguardClockSwitch.setKeyguardHidingBigClock(true);
- // THEN the container is gone.
- assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.GONE);
- }
-
- @Test
- public void setKeyguardHidingBigClock_visible() {
- // GIVEN that the container for the big clock has visibility GONE
- mBigClockContainer.setVisibility(GONE);
- mKeyguardClockSwitch.setBigClockContainer(mBigClockContainer, StatusBarState.KEYGUARD);
- // AND the plugin returns a view for the big clock
- ClockPlugin plugin = mock(ClockPlugin.class);
- when(plugin.getBigClockView()).thenReturn(mBigClock);
- // AND in the keyguard state
- mKeyguardClockSwitch.updateBigClockVisibility(StatusBarState.KEYGUARD);
- // WHEN the plugin is connected
- mKeyguardClockSwitch.setClockPlugin(plugin, StatusBarState.KEYGUARD);
- // WHEN the container set hiding clock as false
- mKeyguardClockSwitch.setKeyguardHidingBigClock(false);
- // THEN the container is made visible.
- assertThat(mBigClockContainer.getVisibility()).isEqualTo(View.VISIBLE);
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
index 0074dbea1151..49f1655997ef 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
@@ -23,7 +23,6 @@ import android.testing.AndroidTestingRunner;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -50,8 +49,6 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
@Mock
ConfigurationController mConfigurationController;
@Mock
- NotificationIconAreaController mNotificationIconAreaController;
- @Mock
DozeParameters mDozeParameters;
private KeyguardStatusViewController mController;
@@ -67,7 +64,6 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
mKeyguardStateController,
mKeyguardUpdateMonitor,
mConfigurationController,
- mNotificationIconAreaController,
mDozeParameters);
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/TextAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/TextAnimatorTest.kt
index 7b4f14dd3595..ad7f0cbe1e3a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/TextAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/TextAnimatorTest.kt
@@ -16,6 +16,7 @@
package com.android.keyguard
+import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.testing.AndroidTestingRunner
import android.text.Layout
@@ -25,7 +26,9 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
import org.mockito.Mockito.`when`
+import org.mockito.Mockito.eq
import org.mockito.Mockito.inOrder
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
@@ -107,4 +110,34 @@ class TextAnimatorTest : SysuiTestCase() {
// Then, animation start should not be called.
verify(valueAnimator, never()).start()
}
+
+ @Test
+ fun testAnimationEnded() {
+ val layout = makeLayout("Hello, World", PAINT)
+ val valueAnimator = mock(ValueAnimator::class.java)
+ val textInterpolator = mock(TextInterpolator::class.java)
+ val paint = mock(TextPaint::class.java)
+ `when`(textInterpolator.targetPaint).thenReturn(paint)
+ val animationEndCallback = mock(Runnable::class.java)
+
+ val textAnimator = TextAnimator(layout, {}).apply {
+ this.textInterpolator = textInterpolator
+ this.animator = valueAnimator
+ }
+
+ textAnimator.setTextStyle(
+ weight = 400,
+ animate = true,
+ onAnimationEnd = animationEndCallback
+ )
+
+ // Verify animationEnd callback has been added.
+ val captor = ArgumentCaptor.forClass(AnimatorListenerAdapter::class.java)
+ verify(valueAnimator).addListener(captor.capture())
+ captor.value.onAnimationEnd(valueAnimator)
+
+ // Verify animationEnd callback has been invoked and removed.
+ verify(animationEndCallback).run()
+ verify(valueAnimator).removeListener(eq(captor.value))
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/plugins/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
index 722b0b175b76..6420c4e2c481 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/plugins/animation/ActivityLaunchAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
@@ -1,4 +1,4 @@
-package com.android.systemui.plugins.animation
+package com.android.systemui.animation
import android.app.ActivityManager
import android.app.WindowConfiguration
@@ -35,7 +35,7 @@ import kotlin.concurrent.thread
@RunWith(AndroidTestingRunner::class)
@RunWithLooper
class ActivityLaunchAnimatorTest : SysuiTestCase() {
- private val activityLaunchAnimator = ActivityLaunchAnimator()
+ private val activityLaunchAnimator = ActivityLaunchAnimator(mContext)
private val rootView = View(mContext)
@Spy private val controller = TestLaunchAnimatorController(rootView)
@Mock lateinit var iCallback: IRemoteAnimationFinishedCallback
@@ -96,7 +96,7 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() {
@Test
fun doesNotStartIfAnimationIsCancelled() {
- val runner = ActivityLaunchAnimator.Runner(controller)
+ val runner = activityLaunchAnimator.createRunner(controller)
runner.onAnimationCancelled()
runner.onAnimationStart(0, emptyArray(), emptyArray(), emptyArray(), iCallback)
@@ -107,7 +107,7 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() {
@Test
fun abortsIfNoOpeningWindowIsFound() {
- val runner = ActivityLaunchAnimator.Runner(controller)
+ val runner = activityLaunchAnimator.createRunner(controller)
runner.onAnimationStart(0, emptyArray(), emptyArray(), emptyArray(), iCallback)
waitForIdleSync()
@@ -117,7 +117,7 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() {
@Test
fun startsAnimationIfWindowIsOpening() {
- val runner = ActivityLaunchAnimator.Runner(controller)
+ val runner = activityLaunchAnimator.createRunner(controller)
runner.onAnimationStart(0, arrayOf(fakeWindow()), emptyArray(), emptyArray(), iCallback)
waitForIdleSync()
verify(controller).onLaunchAnimationStart(anyBoolean())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
index e6aeee7a9184..f077190168be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
@@ -35,6 +35,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.sensors.ProximitySensor;
import com.android.systemui.util.sensors.ThresholdSensor;
import com.android.systemui.util.time.FakeSystemClock;
@@ -65,6 +66,8 @@ public class FalsingCollectorImplTest extends SysuiTestCase {
private SysuiStatusBarStateController mStatusBarStateController;
@Mock
private KeyguardStateController mKeyguardStateController;
+ private final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
+ private final FakeExecutor mFakeExecutor = new FakeExecutor(mFakeSystemClock);
@Before
public void setUp() {
@@ -75,7 +78,8 @@ public class FalsingCollectorImplTest extends SysuiTestCase {
mFalsingCollector = new FalsingCollectorImpl(mFalsingDataProvider, mFalsingManager,
mKeyguardUpdateMonitor, mHistoryTracker, mProximitySensor,
- mStatusBarStateController, mKeyguardStateController, new FakeSystemClock());
+ mStatusBarStateController, mKeyguardStateController, mFakeExecutor,
+ mFakeSystemClock);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java
index b6729adeb9b3..2f78532b9e71 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java
@@ -17,7 +17,6 @@
package com.android.systemui.keyguard;
-import static com.android.keyguard.KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1;
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY;
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_DISCLOSURE;
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_OWNER_INFO;
@@ -77,7 +76,7 @@ public class KeyguardIndicationRotateTextViewControllerTest extends SysuiTestCas
MockitoAnnotations.initMocks(this);
when(mView.getTextColors()).thenReturn(ColorStateList.valueOf(Color.WHITE));
mController = new KeyguardIndicationRotateTextViewController(mView, mExecutor,
- mStatusBarStateController, LOCK_SCREEN_MODE_LAYOUT_1);
+ mStatusBarStateController);
mController.onViewAttached();
verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index af677c9d9f64..73b0a6b9a11a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -210,16 +210,16 @@ public class MediaControlPanelTest : SysuiTestCase() {
fun bindWhenUnattached() {
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, null, null, device, true, null)
- player.bind(state, PACKAGE)
+ player.bindPlayer(state, PACKAGE)
assertThat(player.isPlaying()).isFalse()
}
@Test
fun bindText() {
- player.attach(holder)
+ player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, session.getSessionToken(), null, device, true, null)
- player.bind(state, PACKAGE)
+ player.bindPlayer(state, PACKAGE)
assertThat(appName.getText()).isEqualTo(APP)
assertThat(titleText.getText()).isEqualTo(TITLE)
assertThat(artistText.getText()).isEqualTo(ARTIST)
@@ -227,10 +227,10 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun bindBackgroundColor() {
- player.attach(holder)
+ player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, session.getSessionToken(), null, device, true, null)
- player.bind(state, PACKAGE)
+ player.bindPlayer(state, PACKAGE)
val list = ArgumentCaptor.forClass(ColorStateList::class.java)
verify(view).setBackgroundTintList(list.capture())
assertThat(list.value).isEqualTo(ColorStateList.valueOf(BG_COLOR))
@@ -238,10 +238,10 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun bindDevice() {
- player.attach(holder)
+ player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, session.getSessionToken(), null, device, true, null)
- player.bind(state, PACKAGE)
+ player.bindPlayer(state, PACKAGE)
assertThat(seamlessText.getText()).isEqualTo(DEVICE_NAME)
assertThat(seamless.isEnabled()).isTrue()
}
@@ -250,10 +250,10 @@ public class MediaControlPanelTest : SysuiTestCase() {
fun bindDisabledDevice() {
seamless.id = 1
seamlessFallback.id = 2
- player.attach(holder)
+ player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, session.getSessionToken(), null, disabledDevice, true, null)
- player.bind(state, PACKAGE)
+ player.bindPlayer(state, PACKAGE)
verify(expandedSet).setVisibility(seamless.id, View.GONE)
verify(expandedSet).setVisibility(seamlessFallback.id, View.VISIBLE)
verify(collapsedSet).setVisibility(seamless.id, View.GONE)
@@ -262,10 +262,10 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun bindNullDevice() {
- player.attach(holder)
+ player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, session.getSessionToken(), null, null, true, null)
- player.bind(state, PACKAGE)
+ player.bindPlayer(state, PACKAGE)
assertThat(seamless.isEnabled()).isTrue()
assertThat(seamlessText.getText()).isEqualTo(context.getResources().getString(
com.android.internal.R.string.ext_media_seamless_action))
@@ -273,18 +273,18 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun bindDeviceResumptionPlayer() {
- player.attach(holder)
+ player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, session.getSessionToken(), null, device, true, null,
resumption = true)
- player.bind(state, PACKAGE)
+ player.bindPlayer(state, PACKAGE)
assertThat(seamlessText.getText()).isEqualTo(DEVICE_NAME)
assertThat(seamless.isEnabled()).isFalse()
}
@Test
fun longClick_gutsClosed() {
- player.attach(holder)
+ player.attachPlayer(holder)
whenever(mediaViewController.isGutsVisible).thenReturn(false)
val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
@@ -296,7 +296,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun longClick_gutsOpen() {
- player.attach(holder)
+ player.attachPlayer(holder)
whenever(mediaViewController.isGutsVisible).thenReturn(true)
val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
@@ -308,7 +308,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun cancelButtonClick_animation() {
- player.attach(holder)
+ player.attachPlayer(holder)
cancel.callOnClick()
@@ -317,7 +317,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun settingsButtonClick() {
- player.attach(holder)
+ player.attachPlayer(holder)
settings.callOnClick()
@@ -330,11 +330,11 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun dismissButtonClick() {
val mediaKey = "key for dismissal"
- player.attach(holder)
+ player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, session.getSessionToken(), null, null, true, null,
notificationKey = KEY)
- player.bind(state, mediaKey)
+ player.bindPlayer(state, mediaKey)
assertThat(dismiss.isEnabled).isEqualTo(true)
dismiss.callOnClick()
@@ -348,11 +348,11 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun dismissButtonDisabled() {
val mediaKey = "key for dismissal"
- player.attach(holder)
+ player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, session.getSessionToken(), null, null, true, null,
isClearable = false, notificationKey = KEY)
- player.bind(state, mediaKey)
+ player.bindPlayer(state, mediaKey)
assertThat(dismiss.isEnabled).isEqualTo(false)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
index e88c72860ed8..96eb4b096931 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
@@ -2,6 +2,7 @@ package com.android.systemui.media
import android.app.Notification.MediaStyle
import android.app.PendingIntent
+import android.app.smartspace.SmartspaceTarget
import android.graphics.Bitmap
import android.media.MediaDescription
import android.media.MediaMetadata
@@ -39,6 +40,8 @@ import org.mockito.Mockito.`when` as whenever
private const val KEY = "KEY"
private const val KEY_2 = "KEY_2"
+private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
+private const val KEY_NONE_MEDIA_SMARTSPACE = "NONE_MEDIA_SMARTSPACE_ID"
private const val PACKAGE_NAME = "com.android.systemui"
private const val APP_NAME = "SystemUI"
private const val SESSION_ARTIST = "artist"
@@ -72,6 +75,8 @@ class MediaDataManagerTest : SysuiTestCase() {
@Mock lateinit var listener: MediaDataManager.Listener
@Mock lateinit var pendingIntent: PendingIntent
@Mock lateinit var activityStarter: ActivityStarter
+ lateinit var smartspaceMediaDataProvider: SmartspaceMediaDataProvider
+ @Mock lateinit var mediaSmartspaceTarget: SmartspaceTarget
lateinit var mediaDataManager: MediaDataManager
lateinit var mediaNotification: StatusBarNotification
@Captor lateinit var mediaDataCaptor: ArgumentCaptor<MediaData>
@@ -80,6 +85,7 @@ class MediaDataManagerTest : SysuiTestCase() {
fun setup() {
foregroundExecutor = FakeExecutor(FakeSystemClock())
backgroundExecutor = FakeExecutor(FakeSystemClock())
+ smartspaceMediaDataProvider = SmartspaceMediaDataProvider()
mediaDataManager = MediaDataManager(
context = context,
backgroundExecutor = backgroundExecutor,
@@ -94,6 +100,7 @@ class MediaDataManagerTest : SysuiTestCase() {
mediaDataCombineLatest = mediaDataCombineLatest,
mediaDataFilter = mediaDataFilter,
activityStarter = activityStarter,
+ smartspaceMediaDataProvider = smartspaceMediaDataProvider,
useMediaResumption = true,
useQsMediaPlayer = true
)
@@ -117,6 +124,9 @@ class MediaDataManagerTest : SysuiTestCase() {
// mock, it doesn't pass those events along the chain to the external listeners. So, just
// treat mediaSessionBasedFilter as a listener for testing.
listener = mediaSessionBasedFilter
+
+ whenever(mediaSmartspaceTarget.smartspaceTargetId).thenReturn(KEY_MEDIA_SMARTSPACE)
+ whenever(mediaSmartspaceTarget.featureType).thenReturn(SmartspaceTarget.FEATURE_MEDIA)
}
@After
@@ -320,4 +330,24 @@ class MediaDataManagerTest : SysuiTestCase() {
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor))
}
+
+ @Test
+ fun testOnSmartspaceMediaDataLoaded_hasNewMediaTarget_callsListener() {
+ smartspaceMediaDataProvider.onTargetsAvailable(listOf(mediaSmartspaceTarget))
+ verify(listener).onSmartspaceMediaDataLoaded(
+ eq(KEY_MEDIA_SMARTSPACE), eq(mediaSmartspaceTarget))
+ }
+
+ @Test
+ fun testOnSmartspaceMediaDataLoaded_hasNoneMediaTarget_notCallsListener() {
+ smartspaceMediaDataProvider.onTargetsAvailable(listOf())
+ verify(listener, never()).onSmartspaceMediaDataLoaded(anyObject(), anyObject())
+ }
+
+ @Test
+ fun testOnSmartspaceMediaDataLoaded_hasNoneMediaTarget_callsRemoveListener() {
+ smartspaceMediaDataProvider.onTargetsAvailable(listOf(mediaSmartspaceTarget))
+ smartspaceMediaDataProvider.onTargetsAvailable(listOf())
+ verify(listener).onSmartspaceMediaDataRemoved(KEY_MEDIA_SMARTSPACE)
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
index d91625eb7fab..7125500c1fe6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
@@ -186,11 +186,11 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
mLauncherApps = mock(LauncherApps.class);
mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager);
mManager = new PeopleSpaceWidgetManager(mContext);
- mManager.setAppWidgetManager(mAppWidgetManager, mIPeopleManager, mPeopleManager,
- mLauncherApps, mNotificationEntryManager, mPackageManager, true);
- mManager.attach(mListenerService);
mProvider = new PeopleSpaceWidgetProvider();
mProvider.setPeopleSpaceWidgetManager(mManager);
+ mManager.setAppWidgetManager(mAppWidgetManager, mIPeopleManager, mPeopleManager,
+ mLauncherApps, mNotificationEntryManager, mPackageManager, true, mProvider);
+ mManager.attach(mListenerService);
verify(mListenerService).addNotificationHandler(mListenerCaptor.capture());
NotificationHandler serviceListener = requireNonNull(mListenerCaptor.getValue());
@@ -842,6 +842,52 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
any());
}
+
+ @Test
+ public void testAddThenReconfigureWidgetsUpdatesStorageCacheAndListeners()
+ throws Exception {
+ clearStorage();
+ mManager.addNewWidget(WIDGET_ID_WITH_SHORTCUT, PERSON_TILE);
+ // Check storage.
+ SharedPreferences widgetSp = mContext.getSharedPreferences(
+ String.valueOf(WIDGET_ID_WITH_SHORTCUT),
+ Context.MODE_PRIVATE);
+ assertThat(widgetSp.getString(PACKAGE_NAME, null)).isEqualTo(TEST_PACKAGE_A);
+ assertThat(widgetSp.getString(PeopleSpaceUtils.SHORTCUT_ID, null)).isEqualTo(
+ PERSON_TILE.getId());
+ assertThat(widgetSp.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(0);
+ // Check listener and caching.
+ verify(mPeopleManager).registerConversationListener(eq(TEST_PACKAGE_A), anyInt(),
+ eq(SHORTCUT_ID), any(),
+ any());
+ verify(mLauncherApps, times(1)).cacheShortcuts(
+ eq(TEST_PACKAGE_A),
+ eq(Arrays.asList(SHORTCUT_ID)), eq(UserHandle.of(0)),
+ eq(LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS));
+
+ // Reconfigure WIDGET_ID_WITH_SHORTCUT from PERSON_TILE to PERSON_TILE_WITH_SAME_URI
+ mManager.addNewWidget(WIDGET_ID_WITH_SHORTCUT, PERSON_TILE_WITH_SAME_URI);
+
+ // Check listener is removed and shortcut is uncached.
+ verify(mPeopleManager).unregisterConversationListener(any());
+ verify(mLauncherApps).uncacheShortcuts(eq(TEST_PACKAGE_A),
+ eq(Arrays.asList(PERSON_TILE.getId())), eq(UserHandle.of(0)),
+ eq(LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS));
+ // Check reconfigured storage from TEST_PACKAGE_A to B and SHORTCUT_ID to OTHER_SHORTCUT_ID.
+ assertThat(widgetSp.getString(PACKAGE_NAME, null)).isEqualTo(TEST_PACKAGE_B);
+ assertThat(widgetSp.getString(PeopleSpaceUtils.SHORTCUT_ID, null)).isEqualTo(
+ OTHER_SHORTCUT_ID);
+ assertThat(widgetSp.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(0);
+ // Check listener & caching are reconfigured to TEST_PACKAGE_B and OTHER_SHORTCUT_ID.
+ verify(mPeopleManager, times(1)).registerConversationListener(eq(TEST_PACKAGE_B), anyInt(),
+ eq(OTHER_SHORTCUT_ID), any(),
+ any());
+ verify(mLauncherApps, times(1)).cacheShortcuts(
+ eq(TEST_PACKAGE_B),
+ eq(Arrays.asList(OTHER_SHORTCUT_ID)), eq(UserHandle.of(0)),
+ eq(LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS));
+ }
+
@Test
public void testDeleteAllWidgetsForConversationsUncachesShortcutAndRemovesListeners()
throws Exception {
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 28b44d94effb..1baaf6b827f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
@@ -234,6 +234,27 @@ class PrivacyDialogTest : SysuiTestCase() {
}
@Test
+ fun testPhoneCallNotClickable() {
+ val element = PrivacyDialog.PrivacyElement(
+ PrivacyType.TYPE_MICROPHONE,
+ TEST_PACKAGE_NAME,
+ TEST_USER_ID,
+ "App",
+ null,
+ 0L,
+ false,
+ false,
+ true
+ )
+
+ val list = listOf(element)
+ dialog = PrivacyDialog(context, list, starter)
+ dialog.show()
+ assertThat(dialog.requireViewById<View>(R.id.privacy_item).isClickable).isFalse()
+ assertThat(dialog.requireViewById<View>(R.id.chevron).visibility).isEqualTo(View.GONE)
+ }
+
+ @Test
fun testAttribution() {
val element = PrivacyDialog.PrivacyElement(
PrivacyType.TYPE_MICROPHONE,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
index e4b95af1af04..4ee639b6928f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
@@ -102,7 +102,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
mRootView = (ViewGroup) new LayoutInflaterBuilder(mContext)
.replace("ImageView", TestableImageView.class)
.build().inflate(R.layout.quick_settings_footer, null, false);
- mFooter = new QSSecurityFooter(mRootView, mContext, mUserTracker, new Handler(looper),
+ mFooter = new QSSecurityFooter(mRootView, mUserTracker, new Handler(looper),
mActivityStarter, mSecurityController, looper);
mFooterText = mRootView.findViewById(R.id.footer_text);
mFooterIcon = mRootView.findViewById(R.id.footer_icon);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index 7ff056ead653..68ed2a595a46 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -20,7 +20,13 @@ import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY;
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_DISCLOSURE;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_RESTING;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_TRANSIENT;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_TRUST;
+import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_USER_LOCKED;
import static com.google.common.truth.Truth.assertThat;
@@ -29,6 +35,8 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyObject;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
@@ -70,6 +78,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.KeyguardIndication;
import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
import com.android.systemui.statusbar.phone.LockIcon;
@@ -130,6 +139,8 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
private DockManager mDockManager;
@Mock
private KeyguardIndicationRotateTextViewController mRotateTextViewController;
+ @Mock
+ private FalsingManager mFalsingManager;
@Captor
private ArgumentCaptor<DockManager.AlignmentStateListener> mAlignmentListener;
@Captor
@@ -197,7 +208,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
mController = new KeyguardIndicationController(mContext, mWakeLockBuilder,
mKeyguardStateController, mStatusBarStateController, mKeyguardUpdateMonitor,
mDockManager, mBroadcastDispatcher, mDevicePolicyManager, mIBatteryStats,
- mUserManager, mExecutor);
+ mUserManager, mExecutor, mFalsingManager);
mController.setIndicationArea(mIndicationArea);
verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
mStatusBarStateListener = mStatusBarStateListenerCaptor.getValue();
@@ -227,10 +238,11 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
});
mInstrumentation.waitForIdleSync();
- assertThat(mTextView.getText()).isEqualTo(
+
+ verifyIndicationMessage(INDICATION_TYPE_ALIGNMENT,
mContext.getResources().getString(R.string.dock_alignment_slow_charging));
- assertThat(mTextView.getCurrentTextColor()).isEqualTo(
- Utils.getColorError(mContext).getDefaultColor());
+ assertThat(mKeyguardIndicationCaptor.getValue().getTextColor())
+ .isEqualTo(Utils.getColorError(mContext));
}
@Test
@@ -244,10 +256,10 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
});
mInstrumentation.waitForIdleSync();
- assertThat(mTextView.getText()).isEqualTo(
+ verifyIndicationMessage(INDICATION_TYPE_ALIGNMENT,
mContext.getResources().getString(R.string.dock_alignment_not_charging));
- assertThat(mTextView.getCurrentTextColor()).isEqualTo(
- Utils.getColorError(mContext).getDefaultColor());
+ assertThat(mKeyguardIndicationCaptor.getValue().getTextColor())
+ .isEqualTo(Utils.getColorError(mContext));
}
@Test
@@ -293,9 +305,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(false);
sendUpdateDisclosureBroadcast();
- verify(mRotateTextViewController).hideIndication(INDICATION_TYPE_DISCLOSURE);
- verify(mRotateTextViewController, never()).updateIndication(eq(INDICATION_TYPE_DISCLOSURE),
- any(), anyBoolean());
+ verifyHideIndication(INDICATION_TYPE_DISCLOSURE);
}
@Test
@@ -305,10 +315,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
sendUpdateDisclosureBroadcast();
- verify(mRotateTextViewController).updateIndication(eq(INDICATION_TYPE_DISCLOSURE),
- mKeyguardIndicationCaptor.capture(), eq(false));
- assertThat(mKeyguardIndicationCaptor.getValue().getMessage())
- .isEqualTo(mDisclosureGeneric);
+ verifyIndicationMessage(INDICATION_TYPE_DISCLOSURE, mDisclosureGeneric);
}
@Test
@@ -320,10 +327,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
when(mDevicePolicyManager.getOrganizationNameForUser(eq(10))).thenReturn(null);
sendUpdateDisclosureBroadcast();
- verify(mRotateTextViewController).updateIndication(eq(INDICATION_TYPE_DISCLOSURE),
- mKeyguardIndicationCaptor.capture(), eq(false));
- assertThat(mKeyguardIndicationCaptor.getValue().getMessage())
- .isEqualTo(mDisclosureGeneric);
+ verifyIndicationMessage(INDICATION_TYPE_DISCLOSURE, mDisclosureGeneric);
}
@Test
@@ -333,10 +337,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME);
sendUpdateDisclosureBroadcast();
- verify(mRotateTextViewController).updateIndication(eq(INDICATION_TYPE_DISCLOSURE),
- mKeyguardIndicationCaptor.capture(), eq(false));
- assertThat(mKeyguardIndicationCaptor.getValue().getMessage())
- .isEqualTo(mDisclosureWithOrganization);
+ verifyIndicationMessage(INDICATION_TYPE_DISCLOSURE, mDisclosureWithOrganization);
}
@Test
@@ -348,10 +349,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
when(mDevicePolicyManager.getOrganizationNameForUser(eq(10))).thenReturn(ORGANIZATION_NAME);
sendUpdateDisclosureBroadcast();
- verify(mRotateTextViewController).updateIndication(eq(INDICATION_TYPE_DISCLOSURE),
- mKeyguardIndicationCaptor.capture(), eq(false));
- assertThat(mKeyguardIndicationCaptor.getValue().getMessage())
- .isEqualTo(mDisclosureWithOrganization);
+ verifyIndicationMessage(INDICATION_TYPE_DISCLOSURE, mDisclosureWithOrganization);
}
@Test
@@ -363,26 +361,20 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
sendUpdateDisclosureBroadcast();
- verify(mRotateTextViewController).updateIndication(eq(INDICATION_TYPE_DISCLOSURE),
- mKeyguardIndicationCaptor.capture(), eq(false));
- assertThat(mKeyguardIndicationCaptor.getValue().getMessage())
- .isEqualTo(mDisclosureGeneric);
+ verifyIndicationMessage(INDICATION_TYPE_DISCLOSURE, mDisclosureGeneric);
reset(mRotateTextViewController);
when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME);
sendUpdateDisclosureBroadcast();
- verify(mRotateTextViewController).updateIndication(eq(INDICATION_TYPE_DISCLOSURE),
- mKeyguardIndicationCaptor.capture(), eq(false));
- assertThat(mKeyguardIndicationCaptor.getValue().getMessage())
- .isEqualTo(mDisclosureWithOrganization);
+ verifyIndicationMessage(INDICATION_TYPE_DISCLOSURE, mDisclosureWithOrganization);
reset(mRotateTextViewController);
when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
sendUpdateDisclosureBroadcast();
- verify(mRotateTextViewController).hideIndication(INDICATION_TYPE_DISCLOSURE);
+ verifyHideIndication(INDICATION_TYPE_DISCLOSURE);
}
@Test
@@ -395,10 +387,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
.thenReturn(DEVICE_OWNER_TYPE_FINANCED);
sendUpdateDisclosureBroadcast();
- verify(mRotateTextViewController).updateIndication(eq(INDICATION_TYPE_DISCLOSURE),
- mKeyguardIndicationCaptor.capture(), eq(false));
- assertThat(mKeyguardIndicationCaptor.getValue().getMessage())
- .isEqualTo(mFinancedDisclosureWithOrganization);
+ verifyIndicationMessage(INDICATION_TYPE_DISCLOSURE, mFinancedDisclosureWithOrganization);
}
@Test
@@ -462,10 +451,11 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
mController.getKeyguardCallback().onBiometricHelp(
KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED, message,
BiometricSourceType.FACE);
- assertThat(mTextView.getText()).isEqualTo(message);
+ verifyTransientMessage(message);
+ reset(mRotateTextViewController);
mStatusBarStateListener.onDozingChanged(true);
- assertThat(mTextView.getText()).isNotEqualTo(message);
+ verifyHideIndication(INDICATION_TYPE_TRANSIENT);
}
@Test
@@ -477,7 +467,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
mController.getKeyguardCallback().onBiometricError(FaceManager.FACE_ERROR_TIMEOUT,
"A message", BiometricSourceType.FACE);
- assertThat(mTextView.getText()).isEqualTo(message);
+ verifyTransientMessage(message);
mStatusBarStateListener.onDozingChanged(true);
assertThat(mTextView.getText()).isNotEqualTo(message);
@@ -503,19 +493,22 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
reset(mKeyguardUpdateMonitor);
mController.setVisible(true);
- assertThat(mTextView.getText()).isEqualTo(
+ verifyIndicationMessage(INDICATION_TYPE_USER_LOCKED,
mContext.getString(com.android.internal.R.string.lockscreen_storage_locked));
+ reset(mRotateTextViewController);
when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true);
when(mKeyguardUpdateMonitor.isUserUnlocked(anyInt())).thenReturn(true);
mController.setRestingIndication(restingIndication);
- assertThat(mTextView.getText()).isEqualTo(mController.getTrustGrantedIndication());
+ verifyHideIndication(INDICATION_TYPE_USER_LOCKED);
+ verifyIndicationMessage(INDICATION_TYPE_RESTING, restingIndication);
+ reset(mRotateTextViewController);
reset(mKeyguardUpdateMonitor);
when(mKeyguardUpdateMonitor.isUserUnlocked(anyInt())).thenReturn(true);
when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(false);
mController.onUnlockedChanged();
- assertThat(mTextView.getText()).isEqualTo(restingIndication);
+ verifyIndicationMessage(INDICATION_TYPE_RESTING, restingIndication);
}
@Test
@@ -567,12 +560,10 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true);
mController.setPowerPluggedIn(true);
mController.setVisible(true);
- String powerIndication = mController.computePowerIndication();
- String pluggedIndication = mContext.getString(R.string.keyguard_indication_trust_unlocked);
- pluggedIndication = mContext.getString(
- R.string.keyguard_indication_trust_unlocked_plugged_in,
- pluggedIndication, powerIndication);
- assertThat(mTextView.getText()).isEqualTo(pluggedIndication);
+
+ verifyIndicationMessage(
+ INDICATION_TYPE_TRUST,
+ mContext.getString(R.string.keyguard_indication_trust_unlocked));
}
@Test
@@ -586,10 +577,11 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
mController.getKeyguardCallback().onRefreshBatteryInfo(status);
mController.setVisible(true);
- String percentage = NumberFormat.getPercentInstance().format(80 / 100f);
- String pluggedIndication = mContext.getString(
- R.string.keyguard_plugged_in_charging_limited, percentage);
- assertThat(mTextView.getText()).isEqualTo(pluggedIndication);
+ verifyIndicationMessage(
+ INDICATION_TYPE_BATTERY,
+ mContext.getString(
+ R.string.keyguard_plugged_in_charging_limited,
+ NumberFormat.getPercentInstance().format(80 / 100f)));
}
@Test
@@ -603,10 +595,11 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
mController.getKeyguardCallback().onRefreshBatteryInfo(status);
mController.setVisible(true);
- String percentage = NumberFormat.getPercentInstance().format(80 / 100f);
- String pluggedIndication = mContext.getString(
- R.string.keyguard_plugged_in_charging_limited, percentage);
- assertThat(mTextView.getText()).isEqualTo(pluggedIndication);
+ verifyIndicationMessage(
+ INDICATION_TYPE_BATTERY,
+ mContext.getString(
+ R.string.keyguard_plugged_in_charging_limited,
+ NumberFormat.getPercentInstance().format(80 / 100f)));
}
@Test
@@ -620,12 +613,13 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
mController.getKeyguardCallback().onRefreshBatteryInfo(status);
mController.setVisible(true);
- String chargedIndication = mContext.getString(R.string.keyguard_charged);
- assertThat(mTextView.getText()).isEqualTo(chargedIndication);
+ verifyIndicationMessage(
+ INDICATION_TYPE_BATTERY,
+ mContext.getString(R.string.keyguard_charged));
}
@Test
- public void onRefreshBatteryInfo_dischargingWithOverheat_presentBatteryPercentage() {
+ public void onRefreshBatteryInfo_dozing_dischargingWithOverheat_presentBatteryPercentage() {
createController();
BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_DISCHARGING,
90 /* level */, 0 /* plugged */, BatteryManager.BATTERY_HEALTH_OVERHEAT,
@@ -646,10 +640,32 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
mController.getKeyguardCallback().onRequireUnlockForNfc();
mController.setVisible(true);
- assertThat(mTextView.getText()).isEqualTo(message);
+ verifyTransientMessage(message);
}
private void sendUpdateDisclosureBroadcast() {
mBroadcastReceiver.onReceive(mContext, new Intent());
}
+
+ private void verifyIndicationMessage(int type, String message) {
+ verify(mRotateTextViewController).updateIndication(eq(type),
+ mKeyguardIndicationCaptor.capture(), anyBoolean());
+ assertThat(mKeyguardIndicationCaptor.getValue().getMessage())
+ .isEqualTo(message);
+ }
+
+ private void verifyHideIndication(int type) {
+ if (type == INDICATION_TYPE_TRANSIENT) {
+ verify(mRotateTextViewController).hideTransient();
+ verify(mRotateTextViewController, never()).showTransient(anyString(), anyBoolean());
+ } else {
+ verify(mRotateTextViewController).hideIndication(type);
+ verify(mRotateTextViewController, never()).updateIndication(eq(type),
+ anyObject(), anyBoolean());
+ }
+ }
+
+ private void verifyTransientMessage(String message) {
+ verify(mRotateTextViewController).showTransient(eq(message), anyBoolean());
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java
index 57278e32d553..a1168f809971 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java
@@ -32,9 +32,9 @@ import android.util.Property;
import android.view.View;
import android.view.animation.Interpolator;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.notification.stack.AnimationFilter;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.ViewState;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
index 858227fe7129..5f8eb9e06c68 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
@@ -25,7 +25,6 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
-import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.plugins.DarkIconDispatcher;
@@ -107,9 +106,7 @@ public class NotificationIconAreaControllerTest extends SysuiTestCase {
@Test
public void testAppearResetsTranslation() {
- mController.setupAodIcons(
- mAodIcons,
- KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL);
+ mController.setupAodIcons(mAodIcons);
when(mDozeParameters.shouldControlScreenOff()).thenReturn(false);
mController.appearAodIcons();
verify(mAodIcons).setTranslationY(0);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 7d052b910cc6..cebf8be49150 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -39,6 +39,7 @@ import android.content.res.Resources;
import android.hardware.biometrics.BiometricSourceType;
import android.os.PowerManager;
import android.os.UserManager;
+import android.service.quickaccesswallet.QuickAccessWalletClient;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.DisplayMetrics;
@@ -98,6 +99,8 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
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.wm.shell.animation.FlingAnimationUtils;
import org.junit.Before;
@@ -235,6 +238,8 @@ public class NotificationPanelViewTest extends SysuiTestCase {
private UiEventLogger mUiEventLogger;
@Mock
private LockIconViewController mLockIconViewController;
+ @Mock
+ private QuickAccessWalletClient mQuickAccessWalletClient;
private SysuiStatusBarStateController mStatusBarStateController;
private NotificationPanelViewController mNotificationPanelViewController;
@@ -339,7 +344,9 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mNotificationShadeDepthController,
mAmbientState,
mLockIconViewController,
- mFeatureFlags);
+ mFeatureFlags,
+ mQuickAccessWalletClient,
+ new FakeExecutor(new FakeSystemClock()));
mNotificationPanelViewController.initDependencies(
mStatusBar,
mNotificationShelfController);
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 123e4ef446b9..8633eb466b6c 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
@@ -70,6 +70,7 @@ import org.mockito.stubbing.Answer;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
+import java.util.Map;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -245,13 +246,14 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.transitionTo(ScrimState.KEYGUARD);
finishAnimationsImmediately();
- assertScrimAlpha(TRANSPARENT /* front */,
- SEMI_TRANSPARENT /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, SEMI_TRANSPARENT));
- assertScrimTint(true /* front */,
- true /* behind */,
- false /* bubble */);
+ assertScrimTinted(Map.of(
+ mScrimInFront, true,
+ mScrimBehind, true,
+ mScrimForBubble, false));
}
@Test
@@ -259,13 +261,15 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
finishAnimationsImmediately();
- assertScrimAlpha(TRANSPARENT /* front */,
- OPAQUE /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, OPAQUE));
- assertScrimTint(false /* front */,
- true /* behind */,
- false /* bubble */);
+ assertScrimTinted(Map.of(
+ mScrimInFront, false,
+ mScrimBehind, true,
+ mScrimForBubble, false
+ ));
}
@Test
@@ -273,13 +277,15 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.transitionTo(ScrimState.OFF);
finishAnimationsImmediately();
- assertScrimAlpha(OPAQUE /* front */,
- OPAQUE /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, OPAQUE,
+ mScrimBehind, OPAQUE));
- assertScrimTint(true /* front */,
- true /* behind */,
- false /* bubble */);
+ assertScrimTinted(Map.of(
+ mScrimInFront, true,
+ mScrimBehind, true,
+ mScrimForBubble, false
+ ));
}
@Test
@@ -287,13 +293,16 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.transitionTo(ScrimState.AOD);
finishAnimationsImmediately();
- assertScrimAlpha(TRANSPARENT /* front */,
- OPAQUE /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, OPAQUE,
+ mNotificationsScrim, TRANSPARENT));
- assertScrimTint(true /* front */,
- true /* behind */,
- false /* bubble */);
+ assertScrimTinted(Map.of(
+ mScrimInFront, true,
+ mScrimBehind, true,
+ mScrimForBubble, false
+ ));
}
@Test
@@ -302,17 +311,17 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.transitionTo(ScrimState.AOD);
finishAnimationsImmediately();
- assertScrimAlpha(TRANSPARENT /* front */,
- TRANSPARENT /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, TRANSPARENT));
// Pulsing notification should conserve AOD wallpaper.
mScrimController.transitionTo(ScrimState.PULSING);
finishAnimationsImmediately();
- assertScrimAlpha(TRANSPARENT /* front */,
- TRANSPARENT /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, TRANSPARENT));
}
@Test
@@ -322,13 +331,15 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.transitionTo(ScrimState.AOD);
finishAnimationsImmediately();
- assertScrimAlpha(TRANSPARENT /* front */,
- OPAQUE /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, OPAQUE));
- assertScrimTint(true /* front */,
- true /* behind */,
- false /* bubble */);
+ assertScrimTinted(Map.of(
+ mScrimInFront, true,
+ mScrimBehind, true,
+ mScrimForBubble, false
+ ));
}
@Test
@@ -339,13 +350,15 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setHasBackdrop(true);
finishAnimationsImmediately();
- assertScrimAlpha(TRANSPARENT /* front */,
- OPAQUE /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, OPAQUE));
- assertScrimTint(true /* front */,
- true /* behind */,
- false /* bubble */);
+ assertScrimTinted(Map.of(
+ mScrimInFront, true,
+ mScrimBehind, true,
+ mScrimForBubble, false
+ ));
}
@Test
@@ -355,31 +368,31 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setAodFrontScrimAlpha(0.5f);
finishAnimationsImmediately();
- assertScrimAlpha(TRANSPARENT /* front */,
- SEMI_TRANSPARENT /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, SEMI_TRANSPARENT));
// ... but that it does take effect once we enter the AOD state.
mScrimController.transitionTo(ScrimState.AOD);
finishAnimationsImmediately();
- assertScrimAlpha(SEMI_TRANSPARENT /* front */,
- OPAQUE /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, SEMI_TRANSPARENT,
+ mScrimBehind, OPAQUE));
// ... and that if we set it while we're in AOD, it does take immediate effect.
mScrimController.setAodFrontScrimAlpha(1f);
- assertScrimAlpha(OPAQUE /* front */,
- OPAQUE /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, OPAQUE,
+ mScrimBehind, OPAQUE));
// ... and make sure we recall the previous front scrim alpha even if we transition away
// for a bit.
mScrimController.transitionTo(ScrimState.UNLOCKED);
mScrimController.transitionTo(ScrimState.AOD);
finishAnimationsImmediately();
- assertScrimAlpha(OPAQUE /* front */,
- OPAQUE /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, OPAQUE,
+ mScrimBehind, OPAQUE));
// ... and alpha updates should be completely ignored if always_on is off.
// Passing it forward would mess up the wake-up transition.
@@ -402,17 +415,17 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setAodFrontScrimAlpha(0.5f);
finishAnimationsImmediately();
- assertScrimAlpha(TRANSPARENT /* front */,
- SEMI_TRANSPARENT /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, SEMI_TRANSPARENT));
// ... and doesn't take effect when disabled always_on
mAlwaysOnEnabled = false;
mScrimController.transitionTo(ScrimState.AOD);
finishAnimationsImmediately();
- assertScrimAlpha(OPAQUE /* front */,
- OPAQUE /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, OPAQUE,
+ mScrimBehind, OPAQUE));
// ... but will take effect after docked
when(mDockManager.isDocked()).thenReturn(true);
@@ -420,15 +433,15 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setAodFrontScrimAlpha(0.5f);
mScrimController.transitionTo(ScrimState.AOD);
- assertScrimAlpha(SEMI_TRANSPARENT /* front */,
- OPAQUE /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, SEMI_TRANSPARENT,
+ mScrimBehind, OPAQUE));
// ... and that if we set it while we're in AOD, it does take immediate effect after docked.
mScrimController.setAodFrontScrimAlpha(1f);
- assertScrimAlpha(OPAQUE /* front */,
- OPAQUE /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, OPAQUE,
+ mScrimBehind, OPAQUE));
// Reset value since enums are static.
mScrimController.setAodFrontScrimAlpha(0f);
@@ -442,36 +455,38 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setWallpaperSupportsAmbientMode(false);
mScrimController.transitionTo(ScrimState.AOD);
finishAnimationsImmediately();
- assertScrimAlpha(TRANSPARENT /* front */,
- OPAQUE /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, OPAQUE));
mScrimController.transitionTo(ScrimState.PULSING);
finishAnimationsImmediately();
// Front scrim should be transparent, but tinted
// Back scrim should be semi-transparent so the user can see the wallpaper
// Pulse callback should have been invoked
- assertScrimAlpha(TRANSPARENT /* front */,
- OPAQUE /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, OPAQUE));
- assertScrimTint(true /* front */,
- true /* behind */,
- false /* bubble */);
+ assertScrimTinted(Map.of(
+ mScrimInFront, true,
+ mScrimBehind, true,
+ mScrimForBubble, false
+ ));
// ... and when ambient goes dark, front scrim should be semi-transparent
mScrimController.setAodFrontScrimAlpha(0.5f);
finishAnimationsImmediately();
// Front scrim should be semi-transparent
- assertScrimAlpha(SEMI_TRANSPARENT /* front */,
- OPAQUE /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, SEMI_TRANSPARENT,
+ mScrimBehind, OPAQUE));
mScrimController.setWakeLockScreenSensorActive(true);
finishAnimationsImmediately();
- assertScrimAlpha(SEMI_TRANSPARENT /* front */,
- SEMI_TRANSPARENT /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, SEMI_TRANSPARENT,
+ mScrimBehind, SEMI_TRANSPARENT));
// Reset value since enums are static.
mScrimController.setAodFrontScrimAlpha(0f);
@@ -483,27 +498,29 @@ public class ScrimControllerTest extends SysuiTestCase {
finishAnimationsImmediately();
// Front scrim should be transparent
// Back scrim should be visible without tint
- assertScrimAlpha(TRANSPARENT /* front */,
- OPAQUE /* back */,
- TRANSPARENT /* bubble */);
-
- assertScrimTint(false /* front */,
- false /* behind */,
- false /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, OPAQUE));
+
+ assertScrimTinted(Map.of(
+ mScrimInFront, false,
+ mScrimBehind, false,
+ mScrimForBubble, false
+ ));
}
@Test
public void transitionToBouncer() {
mScrimController.transitionTo(ScrimState.BOUNCER_SCRIMMED);
finishAnimationsImmediately();
- // Front scrim should be transparent
- // Back scrim should be visible without tint
- assertScrimAlpha(OPAQUE /* front */,
- TRANSPARENT /* back */,
- TRANSPARENT /* bubble */);
- assertScrimTint(false /* front */,
- false /* behind */,
- false /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, OPAQUE,
+ mScrimBehind, TRANSPARENT));
+ assertScrimTinted(Map.of(
+ mScrimInFront, false,
+ mScrimBehind, false,
+ mScrimForBubble, false
+ ));
}
@Test
@@ -511,19 +528,21 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setPanelExpansion(0f);
mScrimController.transitionTo(ScrimState.UNLOCKED);
finishAnimationsImmediately();
- assertScrimAlpha(TRANSPARENT /* front */,
- TRANSPARENT /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, TRANSPARENT));
- assertScrimTint(false /* front */,
- true /* behind */,
- false /* bubble */);
+ assertScrimTinted(Map.of(
+ mScrimInFront, false,
+ mScrimBehind, true,
+ mScrimForBubble, false
+ ));
// Back scrim should be visible after start dragging
mScrimController.setPanelExpansion(0.5f);
- assertScrimAlpha(TRANSPARENT /* front */,
- SEMI_TRANSPARENT /* back */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, SEMI_TRANSPARENT));
}
@Test
@@ -531,9 +550,11 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.transitionTo(ScrimState.BUBBLE_EXPANDED);
finishAnimationsImmediately();
- assertScrimTint(false /* front */,
- false /* behind */,
- false /* bubble */);
+ assertScrimTinted(Map.of(
+ mScrimInFront, false,
+ mScrimBehind, false,
+ mScrimForBubble, false
+ ));
// Front scrim should be transparent
Assert.assertEquals(ScrimController.TRANSPARENT,
@@ -589,7 +610,10 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setQsPosition(1f, 999 /* value doesn't matter */);
finishAnimationsImmediately();
- assertScrimAlpha(TRANSPARENT, OPAQUE, TRANSPARENT);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, OPAQUE,
+ mNotificationsScrim, OPAQUE));
}
@Test
@@ -623,21 +647,26 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.transitionTo(ScrimState.UNLOCKED);
// Immediately tinted black after the transition starts
- assertScrimTint(true /* front */,
- true /* behind */,
- true /* bubble */);
+ assertScrimTinted(Map.of(
+ mScrimInFront, true,
+ mScrimBehind, true,
+ mScrimForBubble, true
+ ));
finishAnimationsImmediately();
// All scrims should be transparent at the end of fade transition.
- assertScrimAlpha(TRANSPARENT /* front */,
- TRANSPARENT /* behind */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, TRANSPARENT,
+ mScrimForBubble, TRANSPARENT));
// Make sure at the very end of the animation, we're reset to transparent
- assertScrimTint(false /* front */,
- true /* behind */,
- false /* bubble */);
+ assertScrimTinted(Map.of(
+ mScrimInFront, false,
+ mScrimBehind, true,
+ mScrimForBubble, false
+ ));
}
@Test
@@ -652,9 +681,11 @@ public class ScrimControllerTest extends SysuiTestCase {
// Front scrim should be black in the middle of the transition
Assert.assertTrue("Scrim should be visible during transition. Alpha: "
+ mScrimInFront.getViewAlpha(), mScrimInFront.getViewAlpha() > 0);
- assertScrimTint(true /* front */,
- true /* behind */,
- true /* bubble */);
+ assertScrimTinted(Map.of(
+ mScrimInFront, true,
+ mScrimBehind, true,
+ mScrimForBubble, true
+ ));
Assert.assertSame("Scrim should be visible during transition.",
mScrimVisibility, OPAQUE);
}
@@ -843,15 +874,15 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setKeyguardOccluded(true);
mScrimController.transitionTo(ScrimState.AOD);
finishAnimationsImmediately();
- assertScrimAlpha(TRANSPARENT /* front */,
- OPAQUE /* behind */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, OPAQUE));
mScrimController.transitionTo(ScrimState.PULSING);
finishAnimationsImmediately();
- assertScrimAlpha(TRANSPARENT /* front */,
- OPAQUE /* behind */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, OPAQUE));
}
@Test
@@ -859,15 +890,15 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setWallpaperSupportsAmbientMode(true);
mScrimController.transitionTo(ScrimState.AOD);
finishAnimationsImmediately();
- assertScrimAlpha(TRANSPARENT /* front */,
- TRANSPARENT /* behind */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, TRANSPARENT));
mScrimController.setKeyguardOccluded(true);
finishAnimationsImmediately();
- assertScrimAlpha(TRANSPARENT /* front */,
- OPAQUE /* behind */,
- TRANSPARENT /* bubble */);
+ assertScrimAlpha(Map.of(
+ mScrimInFront, TRANSPARENT,
+ mScrimBehind, OPAQUE));
}
@Test
@@ -926,21 +957,67 @@ public class ScrimControllerTest extends SysuiTestCase {
}
}
- private void assertScrimTint(boolean front, boolean behind, boolean bubble) {
- Assert.assertEquals("Tint test failed at state " + mScrimController.getState()
- + " with scrim: " + getScrimName(mScrimInFront) + " and tint: "
- + Integer.toHexString(mScrimInFront.getTint()),
- front, mScrimInFront.getTint() != Color.TRANSPARENT);
+ @Test
+ public void testScrimsOpaque_whenShadeFullyExpanded() {
+ mScrimController.transitionTo(ScrimState.UNLOCKED);
+ mScrimController.setPanelExpansion(1);
+ // notifications scrim alpha change require calling setQsPosition
+ mScrimController.setQsPosition(0, 300);
+ finishAnimationsImmediately();
- Assert.assertEquals("Tint test failed at state " + mScrimController.getState()
- + " with scrim: " + getScrimName(mScrimBehind) + " and tint: "
- + Integer.toHexString(mScrimBehind.getTint()),
- behind, mScrimBehind.getTint() != Color.TRANSPARENT);
+ Assert.assertEquals("Behind scrim should be opaque",
+ mScrimBehind.getViewAlpha(), 1, 0.0);
+ Assert.assertEquals("Notifications scrim should be opaque",
+ mNotificationsScrim.getViewAlpha(), 1, 0.0);
+ }
- Assert.assertEquals("Tint test failed at state " + mScrimController.getState()
- + " with scrim: " + getScrimName(mScrimForBubble) + " and tint: "
- + Integer.toHexString(mScrimForBubble.getTint()),
- bubble, mScrimForBubble.getTint() != Color.TRANSPARENT);
+ @Test
+ public void testScrimsVisible_whenShadeVisible() {
+ mScrimController.transitionTo(ScrimState.UNLOCKED);
+ mScrimController.setPanelExpansion(0.5f);
+ // notifications scrim alpha change require calling setQsPosition
+ mScrimController.setQsPosition(0, 300);
+
+ assertScrimAlpha(Map.of(
+ mScrimBehind, SEMI_TRANSPARENT,
+ mNotificationsScrim, SEMI_TRANSPARENT,
+ mScrimInFront, TRANSPARENT));
+ }
+
+ @Test
+ public void testScrimsVisible_whenShadeVisibleOnLockscreen() {
+ mScrimController.transitionTo(ScrimState.KEYGUARD);
+ mScrimController.setQsPosition(0.5f, 300);
+
+ assertScrimAlpha(Map.of(
+ mScrimBehind, SEMI_TRANSPARENT,
+ mNotificationsScrim, SEMI_TRANSPARENT,
+ mScrimInFront, TRANSPARENT));
+ }
+
+ @Test
+ public void testNotificationScrimTransparent_whenOnLockscreen() {
+ mScrimController.transitionTo(ScrimState.KEYGUARD);
+ // even if shade is not pulled down, panel has expansion of 1 on the lockscreen
+ mScrimController.setPanelExpansion(1);
+ mScrimController.setQsPosition(0f, /*qs panel bottom*/ 0);
+
+ assertScrimAlpha(Map.of(
+ mScrimBehind, SEMI_TRANSPARENT,
+ mNotificationsScrim, TRANSPARENT));
+ }
+
+ private void assertScrimTinted(Map<ScrimView, Boolean> scrimToTint) {
+ // notifications scrim should have always transparent tint
+ assertScrimTint(mNotificationsScrim, false);
+ scrimToTint.forEach((scrim, hasTint) -> assertScrimTint(scrim, hasTint));
+ }
+
+ private void assertScrimTint(ScrimView scrim, boolean hasTint) {
+ String message = "Tint test failed at state " + mScrimController.getState()
+ + " with scrim: " + getScrimName(scrim) + " and tint: "
+ + Integer.toHexString(scrim.getTint());
+ Assert.assertEquals(message, hasTint, scrim.getTint() != Color.TRANSPARENT);
}
private String getScrimName(ScrimView scrim) {
@@ -956,29 +1033,25 @@ public class ScrimControllerTest extends SysuiTestCase {
return "unknown_scrim";
}
- private void assertScrimAlpha(int front, int behind, int bubble) {
+ /**
+ * If {@link #mScrimForBubble} or {@link #mNotificationsScrim} is not passed in the map
+ * we assume it must be transparent
+ */
+ private void assertScrimAlpha(Map<ScrimView, Integer> scrimToAlpha) {
// Check single scrim visibility.
- Assert.assertEquals("Unexpected front scrim alpha: "
- + mScrimInFront.getViewAlpha(),
- front != TRANSPARENT /* expected */,
- mScrimInFront.getViewAlpha() > TRANSPARENT /* actual */);
-
- Assert.assertEquals("Unexpected back scrim alpha: "
- + mScrimBehind.getViewAlpha(),
- behind != TRANSPARENT /* expected */,
- mScrimBehind.getViewAlpha() > TRANSPARENT /* actual */);
-
- Assert.assertEquals(
- "Unexpected bubble scrim alpha: "
- + mScrimForBubble.getViewAlpha(), /* message */
- bubble != TRANSPARENT /* expected */,
- mScrimForBubble.getViewAlpha() > TRANSPARENT /* actual */);
+ if (!scrimToAlpha.containsKey(mScrimForBubble)) {
+ assertScrimAlpha(mScrimForBubble, TRANSPARENT);
+ }
+ if (!scrimToAlpha.containsKey(mNotificationsScrim)) {
+ assertScrimAlpha(mNotificationsScrim, TRANSPARENT);
+ }
+ scrimToAlpha.forEach((scrimView, alpha) -> assertScrimAlpha(scrimView, alpha));
// Check combined scrim visibility.
final int visibility;
- if (front == OPAQUE || behind == OPAQUE || bubble == OPAQUE) {
+ if (scrimToAlpha.values().contains(OPAQUE)) {
visibility = OPAQUE;
- } else if (front > TRANSPARENT || behind > TRANSPARENT || bubble > TRANSPARENT) {
+ } else if (scrimToAlpha.values().contains(SEMI_TRANSPARENT)) {
visibility = SEMI_TRANSPARENT;
} else {
visibility = TRANSPARENT;
@@ -987,4 +1060,11 @@ public class ScrimControllerTest extends SysuiTestCase {
visibility /* expected */,
mScrimVisibility);
}
+
+ private void assertScrimAlpha(ScrimView scrim, int expectedAlpha) {
+ Assert.assertEquals("Unexpected " + getScrimName(scrim) + " scrim alpha: "
+ + scrim.getViewAlpha(),
+ expectedAlpha != TRANSPARENT /* expected */,
+ scrim.getViewAlpha() > TRANSPARENT /* actual */);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index e34bc0c4a8ec..5170168c174c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -51,9 +51,9 @@ import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.animation.ActivityLaunchAnimator;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
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 9b9937b9e260..abc8da24fdb5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -101,6 +101,7 @@ import com.android.wm.shell.bubbles.BubbleStackView;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.TaskStackListenerImpl;
import com.google.common.collect.ImmutableList;
@@ -206,6 +207,8 @@ public class BubblesTest extends SysuiTestCase {
@Mock
private BubbleLogger mBubbleLogger;
@Mock
+ private TaskStackListenerImpl mTaskStackListener;
+ @Mock
private ShellTaskOrganizer mShellTaskOrganizer;
private TestableBubblePositioner mPositioner;
@@ -287,6 +290,7 @@ public class BubblesTest extends SysuiTestCase {
mWindowManagerShellWrapper,
mLauncherApps,
mBubbleLogger,
+ mTaskStackListener,
mShellTaskOrganizer,
mPositioner,
syncExecutor,
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 b0ec628b638b..1ba7f8aa5e24 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
@@ -94,6 +94,7 @@ import com.android.wm.shell.bubbles.BubbleStackView;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.TaskStackListenerImpl;
import org.junit.Before;
import org.junit.Ignore;
@@ -187,6 +188,8 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase {
@Mock
private BubbleLogger mBubbleLogger;
@Mock
+ private TaskStackListenerImpl mTaskStackListener;
+ @Mock
private ShellTaskOrganizer mShellTaskOrganizer;
private TestableBubblePositioner mPositioner;
@@ -253,6 +256,7 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase {
mWindowManagerShellWrapper,
mLauncherApps,
mBubbleLogger,
+ mTaskStackListener,
mShellTaskOrganizer,
mPositioner,
syncExecutor,
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 a1adb2c6922f..a9a558dca577 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
@@ -31,6 +31,7 @@ import com.android.wm.shell.bubbles.BubbleLogger;
import com.android.wm.shell.bubbles.BubblePositioner;
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.TaskStackListenerImpl;
/**
* Testable BubbleController subclass that immediately synchronizes surfaces.
@@ -47,13 +48,15 @@ public class TestableBubbleController extends BubbleController {
WindowManagerShellWrapper windowManagerShellWrapper,
LauncherApps launcherApps,
BubbleLogger bubbleLogger,
+ TaskStackListenerImpl taskStackListener,
ShellTaskOrganizer shellTaskOrganizer,
BubblePositioner positioner,
ShellExecutor shellMainExecutor,
Handler shellMainHandler) {
super(context, data, Runnable::run, floatingContentCoordinator, dataRepository,
statusBarService, windowManager, windowManagerShellWrapper, launcherApps,
- bubbleLogger, shellTaskOrganizer, positioner, shellMainExecutor, shellMainHandler);
+ bubbleLogger, taskStackListener, shellTaskOrganizer, positioner, shellMainExecutor,
+ shellMainHandler);
setInflateSynchronously(true);
initialize();
}
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index f06a94004110..a48f76ea1ca3 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -264,6 +264,10 @@ message SystemMessage {
// Package: android
NOTE_CARRIER_SUGGESTION_AVAILABLE = 63;
+ // Inform that NAS settings have changed on OS upgrade
+ // Package: android
+ NOTE_NAS_UPGRADE = 64;
+
// 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 25b270ea1a79..ad1406c73c2f 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -7,6 +7,22 @@ package {
default_applicable_licenses: ["frameworks_base_license"],
}
+// Defaults for platform code that runs inside system_server
+java_defaults {
+ name: "platform_service_defaults",
+ plugins: ["error_prone_android_framework"],
+ errorprone: {
+ javacflags: [
+ // "-Xep:AndroidFrameworkBinderIdentity:ERROR",
+ "-Xep:AndroidFrameworkCompatChange:ERROR",
+ // "-Xep:AndroidFrameworkUid:ERROR",
+ // NOTE: only enable to generate local patchfiles
+ // "-XepPatchChecks:refaster:frameworks/base/errorprone/refaster/EfficientXml.java.refaster",
+ // "-XepPatchLocation:/tmp/refaster/",
+ ],
+ },
+}
+
filegroup {
name: "services-main-sources",
srcs: [
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 55490ce6825b..b1eae9edc3d4 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -644,13 +644,12 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
}
@Override
- public boolean createAssociation(String packageName, String macAddress, int userId) {
+ public void createAssociation(String packageName, String macAddress, int userId) {
getContext().enforceCallingOrSelfPermission(
android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES, "createAssociation");
addAssociation(new Association(
userId, macAddress, packageName, null, false, System.currentTimeMillis()));
- return true;
}
private void checkCanCallNotificationApi(String callingPackage) throws RemoteException {
diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java
index 9e126d74b172..c49b8e8e77c6 100644
--- a/services/core/java/com/android/server/BinderCallsStatsService.java
+++ b/services/core/java/com/android/server/BinderCallsStatsService.java
@@ -138,6 +138,12 @@ public class BinderCallsStatsService extends Binder {
private static final String SETTINGS_COLLECT_LATENCY_DATA_KEY = "collect_Latency_data";
private static final String SETTINGS_LATENCY_OBSERVER_SAMPLING_INTERVAL_KEY =
"latency_observer_sampling_interval";
+ private static final String SETTINGS_LATENCY_HISTOGRAM_BUCKET_COUNT_KEY =
+ "latency_histogram_bucket_count";
+ private static final String SETTINGS_LATENCY_HISTOGRAM_FIRST_BUCKET_SIZE_KEY =
+ "latency_histogram_first_bucket_size";
+ private static final String SETTINGS_LATENCY_HISTOGRAM_BUCKET_SCALE_FACTOR_KEY =
+ "latency_histogram_bucket_scale_factor";
private boolean mEnabled;
private final Uri mUri = Settings.Global.getUriFor(Settings.Global.BINDER_CALLS_STATS);
@@ -198,9 +204,20 @@ public class BinderCallsStatsService extends Binder {
mParser.getBoolean(SETTINGS_COLLECT_LATENCY_DATA_KEY,
BinderCallsStats.DEFAULT_COLLECT_LATENCY_DATA));
// Binder latency observer settings.
- mBinderCallsStats.getLatencyObserver().setSamplingInterval(mParser.getInt(
+ BinderLatencyObserver binderLatencyObserver = mBinderCallsStats.getLatencyObserver();
+ binderLatencyObserver.setSamplingInterval(mParser.getInt(
SETTINGS_LATENCY_OBSERVER_SAMPLING_INTERVAL_KEY,
BinderLatencyObserver.PERIODIC_SAMPLING_INTERVAL_DEFAULT));
+ binderLatencyObserver.setHistogramBucketsParams(
+ mParser.getInt(
+ SETTINGS_LATENCY_HISTOGRAM_BUCKET_COUNT_KEY,
+ BinderLatencyObserver.BUCKET_COUNT_DEFAULT),
+ mParser.getInt(
+ SETTINGS_LATENCY_HISTOGRAM_FIRST_BUCKET_SIZE_KEY,
+ BinderLatencyObserver.FIRST_BUCKET_SIZE_DEFAULT),
+ mParser.getFloat(
+ SETTINGS_LATENCY_HISTOGRAM_BUCKET_SCALE_FACTOR_KEY,
+ BinderLatencyObserver.BUCKET_SCALE_FACTOR_DEFAULT));
final boolean enabled =
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 09687d34bb80..d9cc4b41f797 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2279,7 +2279,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
netId = nai.network.getNetId();
}
boolean ok = addLegacyRouteToHost(lp, addr, netId, uid);
- if (DBG) log("requestRouteToHostAddress ok=" + ok);
+ if (DBG) {
+ log("requestRouteToHostAddress " + addr + nai.toShortString() + " ok=" + ok);
+ }
return ok;
} finally {
Binder.restoreCallingIdentity(token);
@@ -4229,7 +4231,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// network, we should respect the user's option and don't need to popup the
// PARTIAL_CONNECTIVITY notification to user again.
nai.networkAgentConfig.acceptPartialConnectivity = accept;
- nai.updateScoreForNetworkAgentConfigUpdate();
+ nai.updateScoreForNetworkAgentUpdate();
rematchAllNetworksAndRequests();
}
@@ -4297,6 +4299,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
if (!nai.avoidUnvalidated) {
nai.avoidUnvalidated = true;
+ nai.updateScoreForNetworkAgentUpdate();
rematchAllNetworksAndRequests();
}
}
@@ -4404,7 +4407,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void updateAvoidBadWifi() {
for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
- nai.updateScoreForNetworkAgentConfigUpdate();
+ nai.updateScoreForNetworkAgentUpdate();
}
rematchAllNetworksAndRequests();
}
@@ -6612,7 +6615,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@NonNull final INetworkOfferCallback callback) {
ensureRunningOnConnectivityServiceThread();
for (final NetworkOfferInfo noi : mNetworkOffers) {
- if (noi.offer.callback.equals(callback)) return noi;
+ if (noi.offer.callback.asBinder().equals(callback.asBinder())) return noi;
}
return null;
}
@@ -7170,6 +7173,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
final NetworkCapabilities prevNc = nai.getAndSetNetworkCapabilities(newNc);
updateUids(nai, prevNc, newNc);
+ nai.updateScoreForNetworkAgentUpdate();
if (nai.getCurrentScore() == oldScore && newNc.equalRequestableCapabilities(prevNc)) {
// If the requestable capabilities haven't changed, and the score hasn't changed, then
@@ -7765,6 +7769,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// all networks except in the case of an underlying network for a VCN.
if (newSatisfier.isNascent()) {
newSatisfier.unlingerRequest(NetworkRequest.REQUEST_ID_NONE);
+ newSatisfier.unsetInactive();
}
// if newSatisfier is not null, then newRequest may not be null.
@@ -8269,6 +8274,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// But it will be removed as soon as the network satisfies a request for the first time.
networkAgent.lingerRequest(NetworkRequest.REQUEST_ID_NONE,
SystemClock.elapsedRealtime(), mNascentDelayMs);
+ networkAgent.setInactive();
// Consider network even though it is not yet validated.
rematchAllNetworksAndRequests();
@@ -9904,7 +9910,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
for (final UserHandle ui : users) {
// Add the rules for all users as this policy is device wide.
- uids.get(pref).add(UserHandle.getUid(ui, uid));
+ uids.get(pref).add(ui.getUid(uid));
}
} catch (PackageManager.NameNotFoundException e) {
// Although this may seem like an error scenario, it is ok that uninstalled
diff --git a/services/core/java/com/android/server/DropBoxManagerService.java b/services/core/java/com/android/server/DropBoxManagerService.java
index 0c3d88445747..a2a232d6f3ec 100644
--- a/services/core/java/com/android/server/DropBoxManagerService.java
+++ b/services/core/java/com/android/server/DropBoxManagerService.java
@@ -88,7 +88,7 @@ public final class DropBoxManagerService extends SystemService {
private static final int DEFAULT_AGE_SECONDS = 3 * 86400;
private static final int DEFAULT_MAX_FILES = 1000;
private static final int DEFAULT_MAX_FILES_LOWRAM = 300;
- private static final int DEFAULT_QUOTA_KB = 5 * 1024;
+ private static final int DEFAULT_QUOTA_KB = 10 * 1024;
private static final int DEFAULT_QUOTA_PERCENT = 10;
private static final int DEFAULT_RESERVE_PERCENT = 10;
private static final int QUOTA_RESCAN_MILLIS = 5000;
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index c7f2f43db131..50040e2dad5f 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -34,7 +34,6 @@ import static android.os.PowerWhitelistManager.REASON_COMPANION_DEVICE_MANAGER;
import static android.os.PowerWhitelistManager.REASON_DENIED;
import static android.os.PowerWhitelistManager.REASON_DEVICE_DEMO_MODE;
import static android.os.PowerWhitelistManager.REASON_DEVICE_OWNER;
-import static android.os.PowerWhitelistManager.REASON_EXEMPTED_PACKAGE;
import static android.os.PowerWhitelistManager.REASON_FGS_BINDING;
import static android.os.PowerWhitelistManager.REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION;
import static android.os.PowerWhitelistManager.REASON_INSTR_BACKGROUND_FGS_PERMISSION;
@@ -289,13 +288,6 @@ public final class ActiveServices {
static final long FGS_BG_START_RESTRICTION_CHANGE_ID = 170668199L;
/**
- * If set to false for a package, the system will *not* exempt it from FGS-BG-start,
- * even if it's in {#code ActiveServices.sFgsBgStartExemptedPackages}.
- */
- @ChangeId
- static final long FGS_BG_START_USE_EXEMPTION_LIST_CHANGE_ID = 175801883;
-
- /**
* If a service can not become foreground service due to BG-FGS-launch restriction or other
* reasons, throws an IllegalStateException.
*/
@@ -303,56 +295,6 @@ public final class ActiveServices {
@EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.S)
static final long FGS_START_EXCEPTION_CHANGE_ID = 174041399L;
- /**
- * Special allowlist that contains packages that are allowed to start FGS even if they target S,
- * without using START_FOREGROUND_SERVICES_FROM_BACKGROUND.
- *
- * Note: we exempt FGS starts if either the "callee" or "caller" match any of the emempted
- * packages. This means:
- * - Exempted apps could call Context.startForegroundService() for services owned by any other
- * apps.
- * - Any apps could call Context.startForegroundService() for services owned by any exempted
- * apps.
- * And the call would succeed.
- */
- private static final ArraySet<String> sFgsBgStartExemptedPackages = new ArraySet<>();
-
- private static final ArrayList<String> sFgsBgStartExemptedPackagePrefixes = new ArrayList<>();
-
- /**
- * List of packages that are exempted from the FGS restriction *for now*.
- *
- * STOPSHIP(/b/176844961) Remove it. Also update ActiveServicesTest.java.
- */
- private static final String[] FGS_BG_START_EXEMPTED_PACKAGES = {
- "com.google.pixel.exo.bootstrapping",
- };
-
- /**
- * List of packages that are exempted from the FGS restriction *for now*. We also allow
- * any packages that
- *
- * STOPSHIP(/b/176844961) Remove it. Also update ActiveServicesTest.java.
- */
- private static final String[] FGS_BG_START_EXEMPTED_PACKAGES_PREFIXED_ALLOWED = {
- "com.android.webview",
- "com.google.android.webview",
- "com.android.chrome",
- "com.google.android.apps.chrome",
- "com.chrome",
- };
-
- static {
- for (String s : FGS_BG_START_EXEMPTED_PACKAGES) {
- sFgsBgStartExemptedPackages.add(s);
- }
-
- for (String s : FGS_BG_START_EXEMPTED_PACKAGES_PREFIXED_ALLOWED) {
- sFgsBgStartExemptedPackages.add(s); // Add it for an exact match.
- sFgsBgStartExemptedPackagePrefixes.add(s + "."); // Add it for an prefix match.
- }
- }
-
final Runnable mLastAnrDumpClearer = new Runnable() {
@Override public void run() {
synchronized (mAm) {
@@ -5857,16 +5799,6 @@ public final class ActiveServices {
}
}
- // NOTE this should always be the last check.
- if (ret == REASON_DENIED) {
- if (isPackageExemptedFromFgsRestriction(callingPackage, callingUid)) {
- ret = REASON_EXEMPTED_PACKAGE;
- } else if (targetService != null && isPackageExemptedFromFgsRestriction(
- targetService.appInfo.packageName, targetService.appInfo.uid)) {
- ret = REASON_EXEMPTED_PACKAGE;
- }
- }
-
if (ret == REASON_DENIED) {
final boolean isCompanionApp = mAm.mInternal.isAssociatedCompanionApp(
UserHandle.getUserId(callingUid), callingUid);
@@ -5889,28 +5821,6 @@ public final class ActiveServices {
return ret;
}
- @VisibleForTesting
- static boolean isPackageExemptedFromFgsRestriction(String packageName, int uid) {
- boolean exempted = false;
- if (sFgsBgStartExemptedPackages.contains(packageName)) {
- exempted = true;
- } else {
- for (String pkg : sFgsBgStartExemptedPackagePrefixes) {
- if (packageName.startsWith(pkg)) {
- exempted = true;
- break;
- }
- }
- }
- if (!exempted) {
- return false; // Package isn't exempted.
- }
- // Allow exempted packages to be subject to the restriction using this compat ID.
- // (so that, for example, the webview developer will be able to test the restriction
- // locally.)
- return CompatChanges.isChangeEnabled(FGS_BG_START_USE_EXEMPTION_LIST_CHANGE_ID, uid);
- }
-
private static boolean isFgsBgStart(@ReasonCode int code) {
return code != REASON_PROC_STATE_PERSISTENT
&& code != REASON_PROC_STATE_PERSISTENT_UI
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index a737ea7ef7f4..2a1a8971ec8c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -11501,6 +11501,9 @@ public class ActivityManagerService extends IActivityManager.Stub
// and it's not isolated, as we'd need the signal to bookkeeping the dying process list.
restart = app.onCleanupApplicationRecordLSP(mProcessStats, allowRestart,
fromBinderDied || app.isolated /* unlinkDeath */);
+
+ // Cancel pending frozen task if there is any.
+ mOomAdjuster.mCachedAppOptimizer.unscheduleFreezeAppLSP(app);
}
mAppProfiler.onCleanupApplicationRecordLocked(app);
skipCurrentReceiverLocked(app);
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index e4cb15fe8d56..8dc9d03dedb7 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -974,6 +974,16 @@ public final class CachedAppOptimizer {
}
}
+ /**
+ * To be called when the given app is killed.
+ */
+ @GuardedBy({"mAm", "mProcLock"})
+ void unscheduleFreezeAppLSP(ProcessRecord app) {
+ if (mUseFreezer) {
+ mFreezeHandler.removeMessages(SET_FROZEN_PROCESS_MSG, app);
+ }
+ }
+
@VisibleForTesting
static final class LastCompactionStats {
private final long[] mRssAfterCompaction;
diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java
index b44699bab0bb..fb9f2dd58c58 100644
--- a/services/core/java/com/android/server/am/ContentProviderHelper.java
+++ b/services/core/java/com/android/server/am/ContentProviderHelper.java
@@ -1206,10 +1206,10 @@ public class ContentProviderHelper {
}
}
+ if (providers != null) {
+ mService.mSystemThread.installSystemProviders(providers);
+ }
synchronized (this) {
- if (providers != null) {
- mService.mSystemThread.installSystemProviders(providers);
- }
mSystemProvidersInstalled = true;
}
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index fcf82faca850..ffd24587618f 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -385,11 +385,10 @@ final class HistoricalRegistry {
callback.sendResult(new Bundle());
return;
}
- mPersistence.collectHistoricalOpsDLocked(result, uid, packageName,
- attributionTag,
- opNames, filter, beginTimeMillis, endTimeMillis, flags);
-
}
+ mPersistence.collectHistoricalOpsDLocked(result, uid, packageName,
+ attributionTag,
+ opNames, filter, beginTimeMillis, endTimeMillis, flags);
}
}
@@ -577,19 +576,19 @@ final class HistoricalRegistry {
Slog.e(LOG_TAG, "Interaction before persistence initialized");
return;
}
- final List<HistoricalOps> history = mPersistence.readHistoryDLocked();
- clearHistoricalRegistry();
- if (history != null) {
- final int historySize = history.size();
- for (int i = 0; i < historySize; i++) {
- final HistoricalOps ops = history.get(i);
- ops.offsetBeginAndEndTime(offsetMillis);
- }
- if (offsetMillis < 0) {
- pruneFutureOps(history);
- }
- mPersistence.persistHistoricalOpsDLocked(history);
+ }
+ final List<HistoricalOps> history = mPersistence.readHistoryDLocked();
+ clearHistoricalRegistry();
+ if (history != null) {
+ final int historySize = history.size();
+ for (int i = 0; i < historySize; i++) {
+ final HistoricalOps ops = history.get(i);
+ ops.offsetBeginAndEndTime(offsetMillis);
+ }
+ if (offsetMillis < 0) {
+ pruneFutureOps(history);
}
+ mPersistence.persistHistoricalOpsDLocked(history);
}
}
}
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 9b88c9a7b1fb..18d04e94b36f 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -1257,6 +1257,7 @@ public class AudioDeviceInventory {
break;
case AudioSystem.DEVICE_OUT_HDMI:
case AudioSystem.DEVICE_OUT_HDMI_ARC:
+ case AudioSystem.DEVICE_OUT_HDMI_EARC:
configureHdmiPlugIntent(intent, state);
break;
}
@@ -1292,6 +1293,7 @@ public class AudioDeviceInventory {
break;
case AudioSystem.DEVICE_OUT_HDMI:
case AudioSystem.DEVICE_OUT_HDMI_ARC:
+ case AudioSystem.DEVICE_OUT_HDMI_EARC:
connType = AudioRoutesInfo.MAIN_HDMI;
break;
case AudioSystem.DEVICE_OUT_USB_DEVICE:
@@ -1336,7 +1338,8 @@ public class AudioDeviceInventory {
}
final AudioDevicePort devicePort = (AudioDevicePort) port;
if (devicePort.type() != AudioManager.DEVICE_OUT_HDMI
- && devicePort.type() != AudioManager.DEVICE_OUT_HDMI_ARC) {
+ && devicePort.type() != AudioManager.DEVICE_OUT_HDMI_ARC
+ && devicePort.type() != AudioManager.DEVICE_OUT_HDMI_EARC) {
continue;
}
// found an HDMI port: format the list of supported encodings
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 4cec83d4c026..9707aced2de5 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -562,6 +562,7 @@ public class AudioService extends IAudioService.Stub
AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET,
AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
AudioSystem.DEVICE_OUT_HDMI_ARC,
+ AudioSystem.DEVICE_OUT_HDMI_EARC,
AudioSystem.DEVICE_OUT_AUX_LINE));
// Devices for which the volume is always max, no volume panel
Set<Integer> mFullVolumeDevices = new HashSet<>();
@@ -5877,6 +5878,9 @@ public class AudioService extends IAudioService.Stub
if ((device & AudioSystem.DEVICE_OUT_SPEAKER) != 0) {
device = AudioSystem.DEVICE_OUT_SPEAKER;
} else if ((device & AudioSystem.DEVICE_OUT_HDMI_ARC) != 0) {
+ // FIXME(b/184944421): DEVICE_OUT_HDMI_EARC has two bits set,
+ // so it must be handled correctly as it aliases
+ // with DEVICE_OUT_HDMI_ARC | DEVICE_OUT_EARPIECE.
device = AudioSystem.DEVICE_OUT_HDMI_ARC;
} else if ((device & AudioSystem.DEVICE_OUT_SPDIF) != 0) {
device = AudioSystem.DEVICE_OUT_SPDIF;
diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java
index 6017e92afc1c..e11878104db6 100644
--- a/services/core/java/com/android/server/biometrics/AuthSession.java
+++ b/services/core/java/com/android/server/biometrics/AuthSession.java
@@ -645,7 +645,8 @@ public final class AuthSession implements IBinder.DeathRecipient {
case BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED:
case BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED:
if (mTokenEscrow != null) {
- mKeyStore.addAuthToken(mTokenEscrow);
+ final int result = mKeyStore.addAuthToken(mTokenEscrow);
+ Slog.d(TAG, "addAuthToken: " + result);
} else {
Slog.e(TAG, "mTokenEscrow is null");
}
diff --git a/services/core/java/com/android/server/biometrics/BiometricSensor.java b/services/core/java/com/android/server/biometrics/BiometricSensor.java
index c9e148f9b6ff..8a842b53d8e8 100644
--- a/services/core/java/com/android/server/biometrics/BiometricSensor.java
+++ b/services/core/java/com/android/server/biometrics/BiometricSensor.java
@@ -19,10 +19,13 @@ package com.android.server.biometrics;
import static android.hardware.biometrics.BiometricManager.Authenticators;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.content.Context;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.IBiometricAuthenticator;
import android.hardware.biometrics.IBiometricSensorReceiver;
+import android.hardware.biometrics.SensorPropertiesInternal;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
@@ -62,6 +65,7 @@ public abstract class BiometricSensor {
@Retention(RetentionPolicy.SOURCE)
@interface SensorState {}
+ @NonNull private final Context mContext;
public final int id;
public final @Authenticators.Types int oemStrength; // strength as configured by the OEM
public final int modality;
@@ -84,8 +88,9 @@ public abstract class BiometricSensor {
*/
abstract boolean confirmationSupported();
- BiometricSensor(int id, int modality, @Authenticators.Types int strength,
- IBiometricAuthenticator impl) {
+ BiometricSensor(@NonNull Context context, int id, int modality,
+ @Authenticators.Types int strength, IBiometricAuthenticator impl) {
+ this.mContext = context;
this.id = id;
this.modality = modality;
this.oemStrength = strength;
@@ -169,12 +174,19 @@ public abstract class BiometricSensor {
@Override
public String toString() {
+ SensorPropertiesInternal properties = null;
+ try {
+ properties = impl.getSensorProperties(mContext.getOpPackageName());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception", e);
+ }
+
return "ID(" + id + ")"
+ ", oemStrength: " + oemStrength
+ ", updatedStrength: " + mUpdatedStrength
+ ", modality " + modality
+ ", state: " + mSensorState
+ ", cookie: " + mCookie
- + ", authenticator: " + impl;
+ + ", props: " + properties;
}
}
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 70f26aca3f63..cb7c568757e5 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -725,7 +725,7 @@ public class BiometricService extends SystemService {
}
}
- mSensors.add(new BiometricSensor(id, modality, strength, authenticator) {
+ mSensors.add(new BiometricSensor(getContext(), id, modality, strength, authenticator) {
@Override
boolean confirmationAlwaysRequired(int userId) {
return mSettingObserver.getConfirmationAlwaysRequired(modality, userId);
@@ -1351,13 +1351,8 @@ public class BiometricService extends SystemService {
for (BiometricSensor sensor : mSensors) {
pw.println(" " + sensor);
}
+ pw.println();
pw.println("CurrentSession: " + mCurrentAuthSession);
-
- final List<FingerprintSensorPropertiesInternal> fpProps =
- mInjector.getFingerprintSensorProperties(getContext());
- pw.println("FingerprintSensorProperties: " + fpProps.size());
- for (FingerprintSensorPropertiesInternal prop : fpProps) {
- pw.println(" " + prop);
- }
+ pw.println();
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index 79e75b16dbf2..cf545f37bd43 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -229,7 +229,8 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
getTargetUserId(), mIsStrongBiometric);
} else if (!isBiometricPrompt() && listener != null) {
if (mIsStrongBiometric) {
- KeyStore.getInstance().addAuthToken(byteToken);
+ final int result = KeyStore.getInstance().addAuthToken(byteToken);
+ Slog.d(TAG, "addAuthToken: " + result);
} else {
Slog.d(TAG, "Skipping addAuthToken");
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
index 2fe275288f3b..cc27127ac58f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
@@ -559,22 +559,21 @@ public class BiometricScheduler {
}
/**
- * Requests to cancel authentication.
+ * Requests to cancel authentication or detection.
* @param token from the caller, should match the token passed in when requesting authentication
*/
- public void cancelAuthentication(IBinder token) {
+ public void cancelAuthenticationOrDetection(IBinder token) {
if (mCurrentOperation == null) {
Slog.e(getTag(), "Unable to cancel authentication, null operation");
return;
}
- final boolean isAuthenticating =
- mCurrentOperation.mClientMonitor instanceof AuthenticationConsumer;
+ final boolean isCorrectClient = isAuthenticationOrDetectionOperation(mCurrentOperation);
final boolean tokenMatches = mCurrentOperation.mClientMonitor.getToken() == token;
- if (isAuthenticating && tokenMatches) {
- Slog.d(getTag(), "Cancelling authentication: " + mCurrentOperation);
+ if (isCorrectClient && tokenMatches) {
+ Slog.d(getTag(), "Cancelling: " + mCurrentOperation);
cancelInternal(mCurrentOperation);
- } else if (!isAuthenticating) {
+ } else if (!isCorrectClient) {
// Look through the current queue for all authentication clients for the specified
// token, and mark them as STATE_WAITING_IN_QUEUE_CANCELING. Note that we're marking
// all of them, instead of just the first one, since the API surface currently doesn't
@@ -582,7 +581,7 @@ public class BiometricScheduler {
// process. However, this generally does not happen anyway, and would be a class of
// bugs on its own.
for (Operation operation : mPendingOperations) {
- if (operation.mClientMonitor instanceof AuthenticationConsumer
+ if (isAuthenticationOrDetectionOperation(operation)
&& operation.mClientMonitor.getToken() == token) {
Slog.d(getTag(), "Marking " + operation
+ " as STATE_WAITING_IN_QUEUE_CANCELING");
@@ -592,6 +591,13 @@ public class BiometricScheduler {
}
}
+ private boolean isAuthenticationOrDetectionOperation(@NonNull Operation operation) {
+ final boolean isAuthentication = operation.mClientMonitor
+ instanceof AuthenticationConsumer;
+ final boolean isDetection = operation.mClientMonitor instanceof DetectionConsumer;
+ return isAuthentication || isDetection;
+ }
+
/**
* @return the current operation
*/
diff --git a/services/core/java/com/android/server/biometrics/sensors/DetectionConsumer.java b/services/core/java/com/android/server/biometrics/sensors/DetectionConsumer.java
new file mode 100644
index 000000000000..c71c954f0234
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/DetectionConsumer.java
@@ -0,0 +1,24 @@
+/*
+ * 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.biometrics.sensors;
+
+/**
+ * Interface that clients interested/eligible for interaction detection events should implement.
+ */
+public interface DetectionConsumer {
+ void onInteractionDetected();
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index 34a86d3e6398..ada84769b9ef 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -296,7 +296,15 @@ public class FaceService extends SystemService implements BiometricServiceCallba
return;
}
- // TODO(b/152413782): Implement this once it's supported in the HAL
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+ if (provider == null) {
+ Slog.w(TAG, "Null provider for detectFace");
+ return;
+ }
+
+ provider.second.scheduleFaceDetect(provider.first, token, userId,
+ new ClientMonitorCallbackConverter(receiver), opPackageName,
+ BiometricsProtoEnums.CLIENT_KEYGUARD);
}
@Override // Binder call
@@ -353,7 +361,13 @@ public class FaceService extends SystemService implements BiometricServiceCallba
return;
}
- // TODO(b/152413782): Implement this once it's supported in the HAL
+ final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+ if (provider == null) {
+ Slog.w(TAG, "Null provider for cancelFaceDetect");
+ return;
+ }
+
+ provider.second.cancelFaceDetect(provider.first, token);
}
@Override // Binder call
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
index 9b6fb0b75c57..6d6c2e9e975f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
@@ -101,12 +101,17 @@ public interface ServiceProvider {
void cancelEnrollment(int sensorId, @NonNull IBinder token);
+ void scheduleFaceDetect(int sensorId, @NonNull IBinder token, int userId,
+ @NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName,
+ int statsClient);
+
+ void cancelFaceDetect(int sensorId, @NonNull IBinder token);
+
void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, boolean restricted, int statsClient,
boolean allowBackgroundAuthentication);
-
void cancelAuthentication(int sensorId, @NonNull IBinder token);
void scheduleRemove(int sensorId, @NonNull IBinder token, int faceId, int userId,
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
new file mode 100644
index 000000000000..0ba731ee8b4b
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
@@ -0,0 +1,102 @@
+/*
+ * 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.biometrics.sensors.face.aidl;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.biometrics.BiometricsProtoEnums;
+import android.hardware.biometrics.common.ICancellationSignal;
+import android.hardware.biometrics.face.ISession;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.server.biometrics.BiometricsProto;
+import com.android.server.biometrics.sensors.AcquisitionClient;
+import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
+import com.android.server.biometrics.sensors.DetectionConsumer;
+
+/**
+ * Performs face detection without exposing any matching information (e.g. accept/reject have the
+ * same haptic, lockout counter is not increased).
+ */
+public class FaceDetectClient extends AcquisitionClient<ISession> implements DetectionConsumer {
+
+ private static final String TAG = "FaceDetectClient";
+
+ private final boolean mIsStrongBiometric;
+ @Nullable private ICancellationSignal mCancellationSignal;
+
+ public FaceDetectClient(@NonNull Context context, @NonNull LazyDaemon<ISession> lazyDaemon,
+ @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int userId,
+ @NonNull String owner, int sensorId, boolean isStrongBiometric, int statsClient) {
+ super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId,
+ BiometricsProtoEnums.MODALITY_FACE, BiometricsProtoEnums.ACTION_AUTHENTICATE,
+ statsClient);
+ mIsStrongBiometric = isStrongBiometric;
+ }
+
+ @Override
+ public void start(@NonNull Callback callback) {
+ super.start(callback);
+ startHalOperation();
+ }
+
+ @Override
+ protected void stopHalOperation() {
+ try {
+ mCancellationSignal.cancel();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception", e);
+ mCallback.onClientFinished(this, false /* success */);
+ }
+ }
+
+ @Override
+ protected void startHalOperation() {
+ try {
+ mCancellationSignal = getFreshDaemon().detectInteraction();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception when requesting face detect", e);
+ mCallback.onClientFinished(this, false /* success */);
+ }
+ }
+
+ @Override
+ public void onInteractionDetected() {
+ vibrateSuccess();
+
+ try {
+ getListener().onDetected(getSensorId(), getTargetUserId(), mIsStrongBiometric);
+ mCallback.onClientFinished(this, true /* success */);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception when sending onDetected", e);
+ mCallback.onClientFinished(this, false /* success */);
+ }
+ }
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_DETECT_INTERACTION;
+ }
+
+ @Override
+ public boolean interruptsPrecedingClients() {
+ return true;
+ }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
index 4fb71ffdaab0..b8bac402f430 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
@@ -110,7 +110,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
Slog.e(getTag(), "Stopping background authentication, top: "
+ topPackage + " currentClient: " + client);
mSensors.valueAt(i).getScheduler()
- .cancelAuthentication(client.getToken());
+ .cancelAuthenticationOrDetection(client.getToken());
}
}
}
@@ -145,7 +145,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
final FaceSensorPropertiesInternal internalProp = new FaceSensorPropertiesInternal(
prop.commonProps.sensorId, prop.commonProps.sensorStrength,
prop.commonProps.maxEnrollmentsPerUser, componentInfo, prop.sensorType,
- false /* supportsFaceDetection */, prop.halControlsPreview,
+ prop.supportsDetectInteraction, prop.halControlsPreview,
false /* resetLockoutRequiresChallenge */);
final Sensor sensor = new Sensor(getTag() + "/" + sensorId, this, mContext, mHandler,
internalProp);
@@ -346,6 +346,25 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
}
@Override
+ public void scheduleFaceDetect(int sensorId, @NonNull IBinder token,
+ int userId, @NonNull ClientMonitorCallbackConverter callback,
+ @NonNull String opPackageName, int statsClient) {
+ mHandler.post(() -> {
+ final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
+ final FaceDetectClient client = new FaceDetectClient(mContext,
+ mSensors.get(sensorId).getLazySession(), token, callback, userId, opPackageName,
+ sensorId, isStrongBiometric, statsClient);
+ scheduleForSensor(sensorId, client);
+ });
+ }
+
+ @Override
+ public void cancelFaceDetect(int sensorId, @NonNull IBinder token) {
+ mHandler.post(() -> mSensors.get(sensorId).getScheduler()
+ .cancelAuthenticationOrDetection(token));
+ }
+
+ @Override
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, boolean restricted, int statsClient,
@@ -364,7 +383,8 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
@Override
public void cancelAuthentication(int sensorId, @NonNull IBinder token) {
- mHandler.post(() -> mSensors.get(sensorId).getScheduler().cancelAuthentication(token));
+ mHandler.post(() -> mSensors.get(sensorId).getScheduler()
+ .cancelAuthenticationOrDetection(token));
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
index 4627a9ddf76a..d56fd1221aa9 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
@@ -338,7 +338,17 @@ public class Sensor {
@Override
public void onInteractionDetected() {
- // no-op
+ mHandler.post(() -> {
+ final BaseClientMonitor client = mScheduler.getCurrentClient();
+ if (!(client instanceof FaceDetectClient)) {
+ Slog.e(mTag, "onInteractionDetected for wrong client: "
+ + Utils.getClientName(client));
+ return;
+ }
+
+ final FaceDetectClient detectClient = (FaceDetectClient) client;
+ detectClient.onInteractionDetected();
+ });
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
index 56fad94640f1..2cb2939cde1d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
@@ -639,6 +639,20 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
}
@Override
+ public void scheduleFaceDetect(int sensorId, @NonNull IBinder token,
+ int userId, @NonNull ClientMonitorCallbackConverter callback,
+ @NonNull String opPackageName, int statsClient) {
+ throw new IllegalStateException("Face detect not supported by IBiometricsFace@1.0. Did you"
+ + "forget to check the supportsFaceDetection flag?");
+ }
+
+ @Override
+ public void cancelFaceDetect(int sensorId, @NonNull IBinder token) {
+ throw new IllegalStateException("Face detect not supported by IBiometricsFace@1.0. Did you"
+ + "forget to check the supportsFaceDetection flag?");
+ }
+
+ @Override
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
int userId, int cookie, @NonNull ClientMonitorCallbackConverter receiver,
@NonNull String opPackageName, boolean restricted, int statsClient,
@@ -658,7 +672,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
@Override
public void cancelAuthentication(int sensorId, @NonNull IBinder token) {
mHandler.post(() -> {
- mScheduler.cancelAuthentication(token);
+ mScheduler.cancelAuthenticationOrDetection(token);
});
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
index 9e9d0eec74ab..45e93a096550 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
@@ -58,6 +58,12 @@ class FingerprintDetectClient extends AcquisitionClient<ISession> {
}
@Override
+ public void start(@NonNull Callback callback) {
+ super.start(callback);
+ startHalOperation();
+ }
+
+ @Override
protected void stopHalOperation() {
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
try {
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index 01fd6419aee0..9851ae08ac3a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -115,7 +115,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
Slog.e(getTag(), "Stopping background authentication, top: "
+ topPackage + " currentClient: " + client);
mSensors.valueAt(i).getScheduler()
- .cancelAuthentication(client.getToken());
+ .cancelAuthenticationOrDetection(client.getToken());
}
}
}
@@ -383,7 +383,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
@Override
public void cancelAuthentication(int sensorId, @NonNull IBinder token) {
- mHandler.post(() -> mSensors.get(sensorId).getScheduler().cancelAuthentication(token));
+ mHandler.post(() -> mSensors.get(sensorId).getScheduler()
+ .cancelAuthenticationOrDetection(token));
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index 7353cc7ab12c..eb78245b0df5 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -144,7 +144,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
&& !client.isAlreadyDone()) {
Slog.e(TAG, "Stopping background authentication, top: "
+ topPackage + " currentClient: " + client);
- mScheduler.cancelAuthentication(client.getToken());
+ mScheduler.cancelAuthenticationOrDetection(client.getToken());
}
}
});
@@ -645,7 +645,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
@Override
public void cancelAuthentication(int sensorId, @NonNull IBinder token) {
- mHandler.post(() -> mScheduler.cancelAuthentication(token));
+ mHandler.post(() -> mScheduler.cancelAuthenticationOrDetection(token));
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintUpdateActiveUserClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintUpdateActiveUserClient.java
index 6776810c2e52..fd38bdd1201e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintUpdateActiveUserClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintUpdateActiveUserClient.java
@@ -69,7 +69,7 @@ public class FingerprintUpdateActiveUserClient extends HalClientMonitor<IBiometr
return;
}
- int firstSdkInt = Build.VERSION.FIRST_SDK_INT;
+ int firstSdkInt = Build.VERSION.DEVICE_INITIAL_SDK_INT;
if (firstSdkInt < Build.VERSION_CODES.BASE) {
Slog.e(TAG, "First SDK version " + firstSdkInt + " is invalid; must be " +
"at least VERSION_CODES.BASE");
diff --git a/services/core/java/com/android/server/connectivity/FullScore.java b/services/core/java/com/android/server/connectivity/FullScore.java
index a8a83fc00491..52da56690721 100644
--- a/services/core/java/com/android/server/connectivity/FullScore.java
+++ b/services/core/java/com/android/server/connectivity/FullScore.java
@@ -91,17 +91,26 @@ public class FullScore {
/** @hide */
public static final int POLICY_IS_INVINCIBLE = 58;
+ // This network has been validated at least once since it was connected, but not explicitly
+ // avoided in UI.
+ // TODO : remove setAvoidUnvalidated and instead disconnect the network when the user
+ // chooses to move away from this network, and remove this flag.
+ /** @hide */
+ public static final int POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD = 57;
+
// To help iterate when printing
@VisibleForTesting
- static final int MIN_CS_MANAGED_POLICY = POLICY_IS_INVINCIBLE;
+ static final int MIN_CS_MANAGED_POLICY = POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD;
@VisibleForTesting
static final int MAX_CS_MANAGED_POLICY = POLICY_IS_VALIDATED;
// Mask for policies in NetworkScore. This should have all bits managed by NetworkScore set
// and all bits managed by FullScore unset. As bits are handled from 0 up in NetworkScore and
- // from 63 down in FullScore, cut at the 32rd bit for simplicity, but change this if some day
+ // from 63 down in FullScore, cut at the 32nd bit for simplicity, but change this if some day
// there are more than 32 bits handled on either side.
- private static final int EXTERNAL_POLICIES_MASK = 0x0000FFFF;
+ // YIELD_TO_BAD_WIFI is temporarily handled by ConnectivityService.
+ private static final long EXTERNAL_POLICIES_MASK =
+ 0x00000000FFFFFFFFL & ~(1L << POLICY_YIELD_TO_BAD_WIFI);
@VisibleForTesting
static @NonNull String policyNameOf(final int policy) {
@@ -115,6 +124,7 @@ public class FullScore {
case POLICY_TRANSPORT_PRIMARY: return "TRANSPORT_PRIMARY";
case POLICY_EXITING: return "EXITING";
case POLICY_IS_INVINCIBLE: return "INVINCIBLE";
+ case POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD: return "EVER_VALIDATED";
}
throw new IllegalArgumentException("Unknown policy : " + policy);
}
@@ -137,6 +147,7 @@ public class FullScore {
* @param score the score supplied by the agent
* @param caps the NetworkCapabilities of the network
* @param config the NetworkAgentConfig of the network
+ * @param everValidated whether this network has ever validated
* @param yieldToBadWiFi whether this network yields to a previously validated wifi gone bad
* @return a FullScore that is appropriate to use for ranking.
*/
@@ -145,12 +156,13 @@ public class FullScore {
// connectivity for backward compatibility.
public static FullScore fromNetworkScore(@NonNull final NetworkScore score,
@NonNull final NetworkCapabilities caps, @NonNull final NetworkAgentConfig config,
- final boolean yieldToBadWiFi) {
+ final boolean everValidated, final boolean yieldToBadWiFi) {
return withPolicies(score.getLegacyInt(), score.getPolicies(),
score.getKeepConnectedReason(),
caps.hasCapability(NET_CAPABILITY_VALIDATED),
caps.hasTransport(TRANSPORT_VPN),
caps.hasCapability(NET_CAPABILITY_NOT_METERED),
+ everValidated,
config.explicitlySelected,
config.acceptUnvalidated,
yieldToBadWiFi,
@@ -179,6 +191,8 @@ public class FullScore {
// Prospective scores are always unmetered, because unmetered networks are stronger
// than metered networks, and it's not known in advance whether the network is metered.
final boolean unmetered = true;
+ // If the offer may validate, then it should be considered to have validated at some point
+ final boolean everValidated = mayValidate;
// The network hasn't been chosen by the user (yet, at least).
final boolean everUserSelected = false;
// Don't assume the user will accept unvalidated connectivity.
@@ -189,8 +203,8 @@ public class FullScore {
// score.
final boolean invincible = score.getLegacyInt() > NetworkRanker.LEGACY_INT_MAX;
return withPolicies(score.getLegacyInt(), score.getPolicies(), KEEP_CONNECTED_NONE,
- mayValidate, vpn, unmetered, everUserSelected, acceptUnvalidated, yieldToBadWiFi,
- invincible);
+ mayValidate, vpn, unmetered, everValidated, everUserSelected, acceptUnvalidated,
+ yieldToBadWiFi, invincible);
}
/**
@@ -204,11 +218,14 @@ public class FullScore {
// telephony factory, so that it depends on the carrier. For now this is handled by
// connectivity for backward compatibility.
public FullScore mixInScore(@NonNull final NetworkCapabilities caps,
- @NonNull final NetworkAgentConfig config, final boolean yieldToBadWifi) {
+ @NonNull final NetworkAgentConfig config,
+ final boolean everValidated,
+ final boolean yieldToBadWifi) {
return withPolicies(mLegacyInt, mPolicies, mKeepConnectedReason,
caps.hasCapability(NET_CAPABILITY_VALIDATED),
caps.hasTransport(TRANSPORT_VPN),
caps.hasCapability(NET_CAPABILITY_NOT_METERED),
+ everValidated,
config.explicitlySelected,
config.acceptUnvalidated,
yieldToBadWifi,
@@ -224,6 +241,7 @@ public class FullScore {
final boolean isValidated,
final boolean isVpn,
final boolean isUnmetered,
+ final boolean everValidated,
final boolean everUserSelected,
final boolean acceptUnvalidated,
final boolean yieldToBadWiFi,
@@ -232,6 +250,7 @@ public class FullScore {
| (isValidated ? 1L << POLICY_IS_VALIDATED : 0)
| (isVpn ? 1L << POLICY_IS_VPN : 0)
| (isUnmetered ? 1L << POLICY_IS_UNMETERED : 0)
+ | (everValidated ? 1L << POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD : 0)
| (everUserSelected ? 1L << POLICY_EVER_USER_SELECTED : 0)
| (acceptUnvalidated ? 1L << POLICY_ACCEPT_UNVALIDATED : 0)
| (yieldToBadWiFi ? 1L << POLICY_YIELD_TO_BAD_WIFI : 0)
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 5d793fdda7b0..4d310cbc06bb 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -707,7 +707,8 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRa
@NonNull final NetworkCapabilities nc) {
final NetworkCapabilities oldNc = networkCapabilities;
networkCapabilities = nc;
- mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig, yieldToBadWiFi());
+ mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig, everValidatedForYield(),
+ yieldToBadWiFi());
final NetworkMonitorManager nm = mNetworkMonitor;
if (nm != null) {
nm.notifyNetworkCapabilitiesChanged(nc);
@@ -893,7 +894,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRa
// Caller must not mutate. This method is called frequently and making a defensive copy
// would be too expensive. This is used by NetworkRanker.Scoreable, so it can be compared
// against other scoreables.
- @Override public NetworkCapabilities getCaps() {
+ @Override public NetworkCapabilities getCapsNoCopy() {
return networkCapabilities;
}
@@ -919,7 +920,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRa
*/
public void setScore(final NetworkScore score) {
mScore = FullScore.fromNetworkScore(score, networkCapabilities, networkAgentConfig,
- yieldToBadWiFi());
+ everValidatedForYield(), yieldToBadWiFi());
}
/**
@@ -927,8 +928,13 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRa
*
* Call this after updating the network agent config.
*/
- public void updateScoreForNetworkAgentConfigUpdate() {
- mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig, yieldToBadWiFi());
+ public void updateScoreForNetworkAgentUpdate() {
+ mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig,
+ everValidatedForYield(), yieldToBadWiFi());
+ }
+
+ private boolean everValidatedForYield() {
+ return everValidated && !avoidUnvalidated;
}
/**
diff --git a/services/core/java/com/android/server/connectivity/NetworkOffer.java b/services/core/java/com/android/server/connectivity/NetworkOffer.java
index 5336593b4065..8285e7a8a3cb 100644
--- a/services/core/java/com/android/server/connectivity/NetworkOffer.java
+++ b/services/core/java/com/android/server/connectivity/NetworkOffer.java
@@ -76,7 +76,7 @@ public class NetworkOffer implements NetworkRanker.Scoreable {
/**
* Get the capabilities filter of this offer
*/
- @Override @NonNull public NetworkCapabilities getCaps() {
+ @Override @NonNull public NetworkCapabilities getCapsNoCopy() {
return caps;
}
@@ -133,7 +133,7 @@ public class NetworkOffer implements NetworkRanker.Scoreable {
* @param previousOffer the previous offer
*/
public void migrateFrom(@NonNull final NetworkOffer previousOffer) {
- if (!callback.equals(previousOffer.callback)) {
+ if (!callback.asBinder().equals(previousOffer.callback.asBinder())) {
throw new IllegalArgumentException("Can only migrate from a previous version of"
+ " the same offer");
}
diff --git a/services/core/java/com/android/server/connectivity/NetworkRanker.java b/services/core/java/com/android/server/connectivity/NetworkRanker.java
index 3aaff59a7484..c123ea75c66c 100644
--- a/services/core/java/com/android/server/connectivity/NetworkRanker.java
+++ b/services/core/java/com/android/server/connectivity/NetworkRanker.java
@@ -26,6 +26,7 @@ import static android.net.NetworkScore.POLICY_YIELD_TO_BAD_WIFI;
import static com.android.server.connectivity.FullScore.POLICY_ACCEPT_UNVALIDATED;
import static com.android.server.connectivity.FullScore.POLICY_EVER_USER_SELECTED;
+import static com.android.server.connectivity.FullScore.POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD;
import static com.android.server.connectivity.FullScore.POLICY_IS_INVINCIBLE;
import static com.android.server.connectivity.FullScore.POLICY_IS_VALIDATED;
import static com.android.server.connectivity.FullScore.POLICY_IS_VPN;
@@ -58,7 +59,7 @@ public class NetworkRanker {
/** Get score of this scoreable */
FullScore getScore();
/** Get capabilities of this scoreable */
- NetworkCapabilities getCaps();
+ NetworkCapabilities getCapsNoCopy();
}
private static final boolean USE_POLICY_RANKING = false;
@@ -158,11 +159,12 @@ public class NetworkRanker {
if (accepted.size() == 1) return accepted.get(0);
if (accepted.size() > 0 && rejected.size() > 0) candidates = new ArrayList<>(accepted);
- // Yield to bad wifi policy : if any wifi has ever been validated, keep only networks
- // that don't yield to such a wifi network.
+ // Yield to bad wifi policy : if any wifi has ever been validated (even if it's now
+ // unvalidated), and unless it's been explicitly avoided when bad in UI, then keep only
+ // networks that don't yield to such a wifi network.
final boolean anyWiFiEverValidated = CollectionUtils.any(candidates,
- nai -> nai.getScore().hasPolicy(POLICY_EVER_USER_SELECTED)
- && nai.getCaps().hasTransport(TRANSPORT_WIFI));
+ nai -> nai.getScore().hasPolicy(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD)
+ && nai.getCapsNoCopy().hasTransport(TRANSPORT_WIFI));
if (anyWiFiEverValidated) {
partitionInto(candidates, nai -> !nai.getScore().hasPolicy(POLICY_YIELD_TO_BAD_WIFI),
accepted, rejected);
@@ -206,18 +208,18 @@ public class NetworkRanker {
for (final Scoreable defaultSubNai : accepted) {
// Remove all networks without the DEFAULT_SUBSCRIPTION policy and the same transports
// as a network that has it.
- final int[] transports = defaultSubNai.getCaps().getTransportTypes();
+ final int[] transports = defaultSubNai.getCapsNoCopy().getTransportTypes();
candidates.removeIf(nai -> !nai.getScore().hasPolicy(POLICY_TRANSPORT_PRIMARY)
- && Arrays.equals(transports, nai.getCaps().getTransportTypes()));
+ && Arrays.equals(transports, nai.getCapsNoCopy().getTransportTypes()));
}
if (1 == candidates.size()) return candidates.get(0);
- // It's guaranteed candidates.size() > 0 because there is at least one with DEFAULT_SUB
- // policy and only those without it were removed.
+ // It's guaranteed candidates.size() > 0 because there is at least one with the
+ // TRANSPORT_PRIMARY policy and only those without it were removed.
// If some of the networks have a better transport than others, keep only the ones with
// the best transports.
for (final int transport : PREFERRED_TRANSPORTS_ORDER) {
- partitionInto(candidates, nai -> nai.getCaps().hasTransport(transport),
+ partitionInto(candidates, nai -> nai.getCapsNoCopy().hasTransport(transport),
accepted, rejected);
if (accepted.size() == 1) return accepted.get(0);
if (accepted.size() > 0 && rejected.size() > 0) {
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 37116797d8d7..28f208b327ad 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -133,7 +133,7 @@ public class PermissionMonitor {
* Get device first sdk version.
*/
public int getDeviceFirstSdkInt() {
- return Build.VERSION.FIRST_SDK_INT;
+ return Build.VERSION.DEVICE_INITIAL_SDK_INT;
}
}
@@ -286,7 +286,7 @@ public class PermissionMonitor {
for (UserHandle user : users) {
if (user == null) continue;
- list.add(UserHandle.getUid(user, app.getKey()));
+ list.add(user.getUid(app.getKey()));
}
}
try {
@@ -555,7 +555,7 @@ public class PermissionMonitor {
final UserHandle handle = UserHandle.of(userId);
if (handle == null) continue;
- final int uid = UserHandle.getUid(handle, appId);
+ final int uid = handle.getUid(appId);
if (range.contains(uid)) {
result.add(uid);
}
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index 4bbd33817d28..67779a2e1685 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -27,6 +27,7 @@ import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.display.DisplayManager;
+import android.hardware.fingerprint.IUdfpsHbmListener;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
@@ -40,14 +41,17 @@ import android.util.IndentingPrintWriter;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.view.Display;
import android.view.DisplayInfo;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
+import com.android.server.LocalServices;
import com.android.server.display.utils.AmbientFilter;
import com.android.server.display.utils.AmbientFilterFactory;
+import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.utils.DeviceConfigInterface;
import java.io.PrintWriter;
@@ -93,6 +97,7 @@ public class DisplayModeDirector {
private final AppRequestObserver mAppRequestObserver;
private final SettingsObserver mSettingsObserver;
private final DisplayObserver mDisplayObserver;
+ private final UdfpsObserver mUdfpsObserver;
private final DeviceConfigInterface mDeviceConfig;
private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings;
@@ -133,6 +138,7 @@ public class DisplayModeDirector {
mSettingsObserver = new SettingsObserver(context, handler);
mDisplayObserver = new DisplayObserver(context, handler);
mBrightnessObserver = new BrightnessObserver(context, handler);
+ mUdfpsObserver = new UdfpsObserver();
mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings();
mDeviceConfig = injector.getDeviceConfig();
mAlwaysRespectAppRequest = false;
@@ -149,6 +155,7 @@ public class DisplayModeDirector {
mSettingsObserver.observe();
mDisplayObserver.observe();
mBrightnessObserver.observe(sensorManager);
+ mUdfpsObserver.observe();
synchronized (mLock) {
// We may have a listener already registered before the call to start, so go ahead and
// notify them to pick up our newly initialized state.
@@ -545,6 +552,7 @@ public class DisplayModeDirector {
mSettingsObserver.dumpLocked(pw);
mAppRequestObserver.dumpLocked(pw);
mBrightnessObserver.dumpLocked(pw);
+ mUdfpsObserver.dumpLocked(pw);
}
}
@@ -566,7 +574,6 @@ public class DisplayModeDirector {
}
final SparseArray<Vote> votes = getOrCreateVotesByDisplay(displayId);
- Vote currentVote = votes.get(priority);
if (vote != null) {
votes.put(priority, vote);
} else {
@@ -649,6 +656,11 @@ public class DisplayModeDirector {
return mSettingsObserver;
}
+ @VisibleForTesting
+ UdfpsObserver getUdpfsObserver() {
+ return mUdfpsObserver;
+ }
+
@VisibleForTesting
DesiredDisplayModeSpecs getDesiredDisplayModeSpecsWithInjectedFpsSettings(
@@ -928,11 +940,15 @@ public class DisplayModeDirector {
// LOW_POWER_MODE force display to [0, 60HZ] if Settings.Global.LOW_POWER_MODE is on.
public static final int PRIORITY_LOW_POWER_MODE = 6;
+ // The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order
+ // to function, so this needs to be the highest priority of all votes.
+ public static final int PRIORITY_UDFPS = 7;
+
// Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and
// APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString.
public static final int MIN_PRIORITY = PRIORITY_DEFAULT_REFRESH_RATE;
- public static final int MAX_PRIORITY = PRIORITY_LOW_POWER_MODE;
+ public static final int MAX_PRIORITY = PRIORITY_UDFPS;
// The cutoff for the app request refresh rate range. Votes with priorities lower than this
// value will not be considered when constructing the app request refresh rate range.
@@ -989,6 +1005,9 @@ public class DisplayModeDirector {
return "PRIORITY_USER_SETTING_PEAK_REFRESH_RATE";
case PRIORITY_LOW_POWER_MODE:
return "PRIORITY_LOW_POWER_MODE";
+ case PRIORITY_UDFPS:
+ return "PRIORITY_UDFPS";
+
default:
return Integer.toString(priority);
}
@@ -1162,7 +1181,7 @@ public class DisplayModeDirector {
}
final class AppRequestObserver {
- private SparseArray<Display.Mode> mAppRequestedModeByDisplay;
+ private final SparseArray<Display.Mode> mAppRequestedModeByDisplay;
AppRequestObserver() {
mAppRequestedModeByDisplay = new SparseArray<>();
@@ -1196,7 +1215,6 @@ public class DisplayModeDirector {
updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, refreshRateVote);
updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_SIZE, sizeVote);
- return;
}
private Display.Mode findModeByIdLocked(int displayId, int modeId) {
@@ -1328,7 +1346,8 @@ public class DisplayModeDirector {
private SensorManager mSensorManager;
private Sensor mLightSensor;
- private LightSensorEventListener mLightSensorListener = new LightSensorEventListener();
+ private final LightSensorEventListener mLightSensorListener =
+ new LightSensorEventListener();
// Take it as low brightness before valid sensor data comes
private float mAmbientLux = -1.0f;
private AmbientFilter mAmbientFilter;
@@ -1559,8 +1578,7 @@ public class DisplayModeDirector {
mLightSensorListener.dumpLocked(pw);
if (mAmbientFilter != null) {
- IndentingPrintWriter ipw = new IndentingPrintWriter(pw);
- ipw.setIndent(" ");
+ IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
mAmbientFilter.dump(ipw);
}
}
@@ -1907,7 +1925,7 @@ public class DisplayModeDirector {
return false;
}
- private Runnable mInjectSensorEventRunnable = new Runnable() {
+ private final Runnable mInjectSensorEventRunnable = new Runnable() {
@Override
public void run() {
long now = SystemClock.uptimeMillis();
@@ -1926,6 +1944,83 @@ public class DisplayModeDirector {
}
}
+ private class UdfpsObserver extends IUdfpsHbmListener.Stub {
+ private final SparseBooleanArray mLocalHbmEnabled = new SparseBooleanArray();
+ private final SparseBooleanArray mGlobalHbmEnabled = new SparseBooleanArray();
+
+ public void observe() {
+ StatusBarManagerInternal statusBar =
+ LocalServices.getService(StatusBarManagerInternal.class);
+ statusBar.setUdfpsHbmListener(this);
+ }
+
+ @Override
+ public void onHbmEnabled(int hbmType, int displayId) {
+ synchronized (mLock) {
+ updateHbmStateLocked(hbmType, displayId, true /*enabled*/);
+ }
+ }
+
+ @Override
+ public void onHbmDisabled(int hbmType, int displayId) {
+ synchronized (mLock) {
+ updateHbmStateLocked(hbmType, displayId, false /*enabled*/);
+ }
+ }
+
+ private void updateHbmStateLocked(int hbmType, int displayId, boolean enabled) {
+ switch (hbmType) {
+ case UdfpsObserver.LOCAL_HBM:
+ mLocalHbmEnabled.put(displayId, enabled);
+ break;
+ case UdfpsObserver.GLOBAL_HBM:
+ mGlobalHbmEnabled.put(displayId, enabled);
+ break;
+ default:
+ Slog.w(TAG, "Unknown HBM type reported. Ignoring.");
+ return;
+ }
+ updateVoteLocked(displayId);
+ }
+
+ private void updateVoteLocked(int displayId) {
+ final Vote vote;
+ if (mGlobalHbmEnabled.get(displayId)) {
+ vote = Vote.forRefreshRates(60f, 60f);
+ } else if (mLocalHbmEnabled.get(displayId)) {
+ Display.Mode[] modes = mSupportedModesByDisplay.get(displayId);
+ float maxRefreshRate = 0f;
+ for (Display.Mode mode : modes) {
+ if (mode.getRefreshRate() > maxRefreshRate) {
+ maxRefreshRate = mode.getRefreshRate();
+ }
+ }
+ vote = Vote.forRefreshRates(maxRefreshRate, maxRefreshRate);
+ } else {
+ vote = null;
+ }
+
+ DisplayModeDirector.this.updateVoteLocked(displayId, Vote.PRIORITY_UDFPS, vote);
+ }
+
+ void dumpLocked(PrintWriter pw) {
+ pw.println(" UdfpsObserver");
+ pw.println(" mLocalHbmEnabled: ");
+ for (int i = 0; i < mLocalHbmEnabled.size(); i++) {
+ final int displayId = mLocalHbmEnabled.keyAt(i);
+ final String enabled = mLocalHbmEnabled.valueAt(i) ? "enabled" : "disabled";
+ pw.println(" Display " + displayId + ": " + enabled);
+ }
+ pw.println(" mGlobalHbmEnabled: ");
+ for (int i = 0; i < mGlobalHbmEnabled.size(); i++) {
+ final int displayId = mGlobalHbmEnabled.keyAt(i);
+ final String enabled = mGlobalHbmEnabled.valueAt(i) ? "enabled" : "disabled";
+ pw.println(" Display " + displayId + ": " + enabled);
+ }
+
+ }
+ }
+
private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener {
public DeviceConfigDisplaySettings() {
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index cb8541eb5e94..5cd0534c8e93 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -140,6 +140,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private static final int RAMP_STATE_SKIP_INITIAL = 1;
private static final int RAMP_STATE_SKIP_AUTOBRIGHT = 2;
+ private static final int REPORTED_TO_POLICY_UNREPORTED = -1;
private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0;
private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1;
private static final int REPORTED_TO_POLICY_SCREEN_ON = 2;
@@ -311,8 +312,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private long mScreenOnBlockStartRealTime;
private long mScreenOffBlockStartRealTime;
- // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_SCREEN_* fields.
- private int mReportedScreenStateToPolicy;
+ // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_* fields.
+ private int mReportedScreenStateToPolicy = REPORTED_TO_POLICY_UNREPORTED;
// If the last recorded screen state was dozing or not.
private boolean mDozing;
@@ -1440,12 +1441,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private boolean setScreenState(int state, boolean reportOnly) {
final boolean isOff = (state == Display.STATE_OFF);
- if (mPowerState.getScreenState() != state) {
+ if (mPowerState.getScreenState() != state
+ || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) {
// If we are trying to turn screen off, give policy a chance to do something before we
// actually turn the screen off.
if (isOff && !mScreenOffBecauseOfProximity) {
- if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON) {
+ if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON
+ || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) {
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);
blockScreenOff();
mWindowManagerPolicy.screenTurningOff(mDisplayId, mPendingScreenOffUnblocker);
@@ -1456,7 +1459,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
}
- if (!reportOnly) {
+ if (!reportOnly && mPowerState.getScreenState() != state) {
Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state);
// TODO(b/153319140) remove when we can get this from the above trace invocation
SystemProperties.set("debug.tracing.screen_state", String.valueOf(state));
@@ -1486,7 +1489,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mWindowManagerPolicy.screenTurnedOff(mDisplayId);
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
}
- if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
+ if (!isOff
+ && (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF
+ || mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED)) {
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON);
if (mPowerState.getColorFadeLevel() == 0.0f) {
blockScreenOn();
diff --git a/services/core/java/com/android/server/graphics/fonts/FontManagerShellCommand.java b/services/core/java/com/android/server/graphics/fonts/FontManagerShellCommand.java
index cf9a79f69f19..5457ef2c77a9 100644
--- a/services/core/java/com/android/server/graphics/fonts/FontManagerShellCommand.java
+++ b/services/core/java/com/android/server/graphics/fonts/FontManagerShellCommand.java
@@ -317,40 +317,45 @@ public class FontManagerShellCommand extends ShellCommand {
"Signature file argument is required.");
}
- // TODO: close fontFd and sigFd.
- ParcelFileDescriptor fontFd = shell.openFileForSystem(fontPath, "r");
- if (fontFd == null) {
- throw new SystemFontException(
- FontManager.RESULT_ERROR_FAILED_TO_OPEN_FONT_FILE,
- "Failed to open font file");
- }
-
- ParcelFileDescriptor sigFd = shell.openFileForSystem(signaturePath, "r");
- if (sigFd == null) {
- throw new SystemFontException(
- FontManager.RESULT_ERROR_FAILED_TO_OPEN_SIGNATURE_FILE,
- "Failed to open signature file");
- }
+ try (ParcelFileDescriptor fontFd = shell.openFileForSystem(fontPath, "r");
+ ParcelFileDescriptor sigFd = shell.openFileForSystem(signaturePath, "r")) {
+ if (fontFd == null) {
+ throw new SystemFontException(
+ FontManager.RESULT_ERROR_FAILED_TO_OPEN_FONT_FILE,
+ "Failed to open font file");
+ }
- try (FileInputStream sigFis = new FileInputStream(sigFd.getFileDescriptor())) {
- int len = sigFis.available();
- if (len > MAX_SIGNATURE_FILE_SIZE_BYTES) {
+ if (sigFd == null) {
throw new SystemFontException(
- FontManager.RESULT_ERROR_SIGNATURE_TOO_LARGE,
- "Signature file is too large");
+ FontManager.RESULT_ERROR_FAILED_TO_OPEN_SIGNATURE_FILE,
+ "Failed to open signature file");
}
- byte[] signature = new byte[len];
- if (sigFis.read(signature, 0, len) != len) {
+
+ byte[] signature;
+ try (FileInputStream sigFis = new FileInputStream(sigFd.getFileDescriptor())) {
+ int len = sigFis.available();
+ if (len > MAX_SIGNATURE_FILE_SIZE_BYTES) {
+ throw new SystemFontException(
+ FontManager.RESULT_ERROR_SIGNATURE_TOO_LARGE,
+ "Signature file is too large");
+ }
+ signature = new byte[len];
+ if (sigFis.read(signature, 0, len) != len) {
+ throw new SystemFontException(
+ FontManager.RESULT_ERROR_INVALID_SIGNATURE_FILE,
+ "Invalid read length");
+ }
+ } catch (IOException e) {
throw new SystemFontException(
FontManager.RESULT_ERROR_INVALID_SIGNATURE_FILE,
- "Invalid read length");
+ "Failed to read signature file.", e);
}
mService.update(
-1, Collections.singletonList(new FontUpdateRequest(fontFd, signature)));
} catch (IOException e) {
- throw new SystemFontException(
- FontManager.RESULT_ERROR_INVALID_SIGNATURE_FILE,
- "Failed to read signature file.", e);
+ // We should reach here only when close() threw IOException.
+ // shell.openFileForSystem() and FontManagerService.update() don't throw IOException.
+ Slog.w(TAG, "Error while closing files", e);
}
shell.getOutPrintWriter().println("Success"); // TODO: Output more details.
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
index 6fbb26c4a5ee..cb05f8fe757a 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
@@ -319,7 +319,7 @@ public class HdmiCecConfig {
Setting powerControlMode = registerSetting(
HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
- R.bool.config_cecSendStandbyOnSleep_userConfigurable);
+ R.bool.config_cecPowerControlMode_userConfigurable);
powerControlMode.registerValue(HdmiControlManager.POWER_CONTROL_MODE_TV,
R.bool.config_cecPowerControlModeTv_allowed,
R.bool.config_cecPowerControlModeTv_default);
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 0f137418a89c..0a800e9fc3a1 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -57,7 +57,7 @@ import android.hardware.lights.LightState;
import android.media.AudioManager;
import android.os.Binder;
import android.os.Bundle;
-import android.os.CombinedVibrationEffect;
+import android.os.CombinedVibration;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
@@ -2033,23 +2033,23 @@ public class InputManagerService extends IInputManager.Stub
// Binder call
@Override
- public void vibrateCombined(int deviceId, CombinedVibrationEffect effect, IBinder token) {
+ public void vibrateCombined(int deviceId, CombinedVibration effect, IBinder token) {
VibratorToken v = getVibratorToken(deviceId, token);
synchronized (v) {
- if (!(effect instanceof CombinedVibrationEffect.Mono)
- && !(effect instanceof CombinedVibrationEffect.Stereo)) {
+ if (!(effect instanceof CombinedVibration.Mono)
+ && !(effect instanceof CombinedVibration.Stereo)) {
Slog.e(TAG, "Only Mono and Stereo effects are supported");
return;
}
v.mVibrating = true;
- if (effect instanceof CombinedVibrationEffect.Mono) {
- CombinedVibrationEffect.Mono mono = (CombinedVibrationEffect.Mono) effect;
+ if (effect instanceof CombinedVibration.Mono) {
+ CombinedVibration.Mono mono = (CombinedVibration.Mono) effect;
VibrationInfo info = new VibrationInfo(mono.getEffect());
nativeVibrate(mPtr, deviceId, info.getPattern(), info.getAmplitudes(),
info.getRepeatIndex(), v.mTokenValue);
- } else if (effect instanceof CombinedVibrationEffect.Stereo) {
- CombinedVibrationEffect.Stereo stereo = (CombinedVibrationEffect.Stereo) effect;
+ } else if (effect instanceof CombinedVibration.Stereo) {
+ CombinedVibration.Stereo stereo = (CombinedVibration.Stereo) effect;
SparseArray<VibrationEffect> effects = stereo.getEffects();
long[] pattern = new long[0];
int repeat = Integer.MIN_VALUE;
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index c4a59c2655a2..202b315a7c82 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -600,11 +600,10 @@ abstract public class ManagedServices {
throws XmlPullParserException, IOException {
// read grants
int type;
- String version = "";
+ String version = XmlUtils.readStringAttribute(parser, ATT_VERSION);
readDefaults(parser);
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
String tag = parser.getName();
- version = XmlUtils.readStringAttribute(parser, ATT_VERSION);
if (type == XmlPullParser.END_TAG
&& getConfig().xmlTag.equals(tag)) {
break;
@@ -642,7 +641,7 @@ abstract public class ManagedServices {
rebindServices(false, USER_ALL);
}
- private void upgradeDefaultsXmlVersion() {
+ void upgradeDefaultsXmlVersion() {
// check if any defaults are loaded
int defaultsSize = mDefaultComponents.size() + mDefaultPackages.size();
if (defaultsSize == 0) {
diff --git a/services/core/java/com/android/server/notification/NASLearnMoreActivity.java b/services/core/java/com/android/server/notification/NASLearnMoreActivity.java
new file mode 100644
index 000000000000..744a44f30ca7
--- /dev/null
+++ b/services/core/java/com/android/server/notification/NASLearnMoreActivity.java
@@ -0,0 +1,51 @@
+/*
+ * 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.notification;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+import com.android.internal.R;
+
+
+public class NASLearnMoreActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ showLearnMoreDialog();
+ }
+
+ private void showLearnMoreDialog() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ AlertDialog alertDialog = builder.setMessage(
+ R.string.nas_upgrade_notification_learn_more_content)
+ .setPositiveButton(R.string.ok,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ NASLearnMoreActivity.this.finish();
+ }
+ })
+ .create();
+ alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+ alertDialog.show();
+ }
+}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 5bcda410f420..bd442bdf9d63 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -265,6 +265,7 @@ import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.SomeArgs;
@@ -619,6 +620,12 @@ public class NotificationManagerService extends SystemService {
private NotificationRecordLogger mNotificationRecordLogger;
private InstanceIdSequence mNotificationInstanceIdSequence;
private Set<String> mMsgPkgsAllowedAsConvos = new HashSet();
+ protected static final String ACTION_ENABLE_NAS =
+ "android.server.notification.action.ENABLE_NAS";
+ protected static final String ACTION_DISABLE_NAS =
+ "android.server.notification.action.DISABLE_NAS";
+ protected static final String ACTION_LEARNMORE_NAS =
+ "android.server.notification.action.LEARNMORE_NAS";
static class Archive {
final SparseArray<Boolean> mEnabled;
@@ -725,6 +732,105 @@ public class NotificationManagerService extends SystemService {
setDefaultAssistantForUser(userId);
}
+ protected void migrateDefaultNASShowNotificationIfNecessary() {
+ final List<UserInfo> activeUsers = mUm.getUsers();
+ for (UserInfo userInfo : activeUsers) {
+ int userId = userInfo.getUserHandle().getIdentifier();
+ if (isNASMigrationDone(userId)) {
+ continue;
+ }
+ if (mAssistants.hasUserSet(userId)) {
+ mAssistants.loadDefaultsFromConfig(false);
+ ComponentName defaultFromConfig = mAssistants.getDefaultFromConfig();
+ List<ComponentName> allowedComponents = mAssistants.getAllowedComponents(userId);
+ if (allowedComponents.contains(defaultFromConfig)) {
+ setNASMigrationDone(userId);
+ mAssistants.resetDefaultFromConfig();
+ continue;
+ }
+ //User selected different NAS or none, need onboarding
+ enqueueNotificationInternal(getContext().getPackageName(),
+ getContext().getOpPackageName(), Binder.getCallingUid(),
+ Binder.getCallingPid(), TAG,
+ SystemMessageProto.SystemMessage.NOTE_NAS_UPGRADE,
+ createNASUpgradeNotification(userId), userId);
+ }
+ }
+ }
+
+ protected Notification createNASUpgradeNotification(int userId) {
+ final Bundle extras = new Bundle();
+ extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
+ getContext().getResources().getString(R.string.global_action_settings));
+ int title = R.string.nas_upgrade_notification_title;
+ int content = R.string.nas_upgrade_notification_content;
+
+ Intent onboardingIntent = new Intent(Settings.ACTION_NOTIFICATION_ASSISTANT_SETTINGS);
+ onboardingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
+ Intent enableIntent = new Intent(ACTION_ENABLE_NAS);
+ enableIntent.putExtra(Intent.EXTRA_USER_ID, userId);
+ PendingIntent enableNASPendingIntent = PendingIntent.getBroadcast(getContext(),
+ 0, enableIntent, PendingIntent.FLAG_IMMUTABLE);
+
+ Intent disableIntent = new Intent(ACTION_DISABLE_NAS);
+ disableIntent.putExtra(Intent.EXTRA_USER_ID, userId);
+ PendingIntent disableNASPendingIntent = PendingIntent.getBroadcast(getContext(),
+ 0, disableIntent, PendingIntent.FLAG_IMMUTABLE);
+
+ Intent learnMoreIntent = new Intent(ACTION_LEARNMORE_NAS);
+ learnMoreIntent.putExtra(Intent.EXTRA_USER_ID, userId);
+ PendingIntent learnNASPendingIntent = PendingIntent.getBroadcast(getContext(),
+ 0, learnMoreIntent, PendingIntent.FLAG_IMMUTABLE);
+
+ Notification.Action enableNASAction = new Notification.Action.Builder(
+ 0,
+ getContext().getResources().getString(
+ R.string.nas_upgrade_notification_enable_action),
+ enableNASPendingIntent).build();
+
+ Notification.Action disableNASAction = new Notification.Action.Builder(
+ 0,
+ getContext().getResources().getString(
+ R.string.nas_upgrade_notification_disable_action),
+ disableNASPendingIntent).build();
+
+ Notification.Action learnMoreNASAction = new Notification.Action.Builder(
+ 0,
+ getContext().getResources().getString(
+ R.string.nas_upgrade_notification_learn_more_action),
+ learnNASPendingIntent).build();
+
+
+ return new Notification.Builder(getContext(), SystemNotificationChannels.ALERTS)
+ .setAutoCancel(false)
+ .setOngoing(true)
+ .setTicker(getContext().getResources().getString(title))
+ .setSmallIcon(R.drawable.ic_settings_24dp)
+ .setContentTitle(getContext().getResources().getString(title))
+ .setContentText(getContext().getResources().getString(content))
+ .setContentIntent(PendingIntent.getActivity(getContext(), 0, onboardingIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
+ .setLocalOnly(true)
+ .setStyle(new Notification.BigTextStyle())
+ .addAction(enableNASAction)
+ .addAction(disableNASAction)
+ .addAction(learnMoreNASAction)
+ .build();
+ }
+
+ @VisibleForTesting
+ void setNASMigrationDone(int userId) {
+ Settings.Secure.putIntForUser(getContext().getContentResolver(),
+ Settings.Secure.NAS_SETTINGS_UPDATED, 1, userId);
+ }
+
+ @VisibleForTesting
+ boolean isNASMigrationDone(int userId) {
+ return (Settings.Secure.getIntForUser(getContext().getContentResolver(),
+ Settings.Secure.NAS_SETTINGS_UPDATED, 0, userId) == 1);
+ }
+
protected void setDefaultAssistantForUser(int userId) {
String overrideDefaultAssistantString = DeviceConfig.getProperty(
DeviceConfig.NAMESPACE_SYSTEMUI,
@@ -1740,6 +1846,41 @@ public class NotificationManagerService extends SystemService {
}
};
+ private final BroadcastReceiver mNASIntentReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ int userId = intent.getIntExtra(Intent.EXTRA_USER_ID, -1);
+ if (ACTION_ENABLE_NAS.equals(action)) {
+ mAssistants.resetDefaultFromConfig();
+ setNotificationAssistantAccessGrantedForUserInternal(
+ CollectionUtils.firstOrNull(mAssistants.getDefaultComponents()),
+ userId, true, true);
+ setNASMigrationDone(userId);
+ cancelNotificationInternal(getContext().getPackageName(),
+ getContext().getOpPackageName(), Binder.getCallingUid(),
+ Binder.getCallingPid(), TAG,
+ SystemMessageProto.SystemMessage.NOTE_NAS_UPGRADE, userId);
+ } else if (ACTION_DISABLE_NAS.equals(action)) {
+ //Set default NAS to be null if user selected none during migration
+ mAssistants.clearDefaults();
+ setNotificationAssistantAccessGrantedForUserInternal(
+ null, userId, true, true);
+ setNASMigrationDone(userId);
+ cancelNotificationInternal(getContext().getPackageName(),
+ getContext().getOpPackageName(), Binder.getCallingUid(),
+ Binder.getCallingPid(), TAG,
+ SystemMessageProto.SystemMessage.NOTE_NAS_UPGRADE, userId);
+ } else if (ACTION_LEARNMORE_NAS.equals(action)) {
+ Intent i = new Intent(getContext(), NASLearnMoreActivity.class);
+ i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ getContext().sendBroadcastAsUser(
+ new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), UserHandle.of(userId));
+ getContext().startActivity(i);
+ }
+ }
+ };
+
private final class SettingsObserver extends ContentObserver {
private final Uri NOTIFICATION_BADGING_URI
= Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_BADGING);
@@ -2263,6 +2404,12 @@ public class NotificationManagerService extends SystemService {
IntentFilter localeChangedFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
getContext().registerReceiver(mLocaleChangeReceiver, localeChangedFilter);
+
+ IntentFilter nasFilter = new IntentFilter();
+ nasFilter.addAction(ACTION_ENABLE_NAS);
+ nasFilter.addAction(ACTION_DISABLE_NAS);
+ nasFilter.addAction(ACTION_LEARNMORE_NAS);
+ getContext().registerReceiver(mNASIntentReceiver, nasFilter);
}
/**
@@ -2274,6 +2421,7 @@ public class NotificationManagerService extends SystemService {
getContext().unregisterReceiver(mNotificationTimeoutReceiver);
getContext().unregisterReceiver(mRestoreReceiver);
getContext().unregisterReceiver(mLocaleChangeReceiver);
+ getContext().unregisterReceiver(mNASIntentReceiver);
if (mDeviceConfigChangedListener != null) {
DeviceConfig.removeOnPropertiesChangedListener(mDeviceConfigChangedListener);
@@ -2529,6 +2677,7 @@ public class NotificationManagerService extends SystemService {
mConditionProviders.onBootPhaseAppsCanStart();
mHistoryManager.onBootPhaseAppsCanStart();
registerDeviceConfigChange();
+ migrateDefaultNASShowNotificationIfNecessary();
} else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
mSnoozeHelper.scheduleRepostsForPersistedNotifications(System.currentTimeMillis());
}
@@ -5021,6 +5170,28 @@ public class NotificationManagerService extends SystemService {
}
@Override
+ public ComponentName getDefaultNotificationAssistant() {
+ checkCallerIsSystem();
+ ArraySet<ComponentName> defaultComponents = mAssistants.getDefaultComponents();
+ if (defaultComponents.size() > 1) {
+ Slog.w(TAG, "More than one default NotificationAssistant: "
+ + defaultComponents.size());
+ }
+ return CollectionUtils.firstOrNull(defaultComponents);
+ }
+
+ @Override
+ public void resetDefaultNotificationAssistant(boolean loadFromConfig) {
+ checkCallerIsSystem();
+ if (loadFromConfig) {
+ mAssistants.resetDefaultFromConfig();
+ } else {
+ mAssistants.clearDefaults();
+ }
+ }
+
+
+ @Override
public boolean hasEnabledNotificationListener(String packageName, int userId) {
checkCallerIsSystem();
return mListeners.isPackageAllowed(packageName, userId);
@@ -9209,8 +9380,14 @@ public class NotificationManagerService extends SystemService {
@GuardedBy("mLock")
private Set<String> mAllowedAdjustments = new ArraySet<>();
+ protected ComponentName mDefaultFromConfig = null;
+
@Override
protected void loadDefaultsFromConfig() {
+ loadDefaultsFromConfig(true);
+ }
+
+ protected void loadDefaultsFromConfig(boolean addToDefault) {
ArraySet<String> assistants = new ArraySet<>();
assistants.addAll(Arrays.asList(mContext.getResources().getString(
com.android.internal.R.string.config_defaultAssistantAccessComponent)
@@ -9228,11 +9405,22 @@ public class NotificationManagerService extends SystemService {
ArraySet<ComponentName> approved = queryPackageForServices(packageName,
MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, USER_SYSTEM);
if (approved.contains(assistantCn)) {
- addDefaultComponentOrPackage(assistantCn.flattenToString());
+ if (addToDefault) {
+ // add the default loaded from config file to mDefaultComponents and
+ // mDefaultPackages
+ addDefaultComponentOrPackage(assistantCn.flattenToString());
+ } else {
+ // otherwise, store in the mDefaultFromConfig for NAS settings migration
+ mDefaultFromConfig = assistantCn;
+ }
}
}
}
+ ComponentName getDefaultFromConfig() {
+ return mDefaultFromConfig;
+ }
+
public NotificationAssistants(Context context, Object lock, UserProfiles up,
IPackageManager pm) {
super(context, lock, up, pm);
@@ -9714,12 +9902,26 @@ public class NotificationManagerService extends SystemService {
for (UserInfo userInfo : activeUsers) {
int userId = userInfo.getUserHandle().getIdentifier();
if (!hasUserSet(userId)) {
+ if (!isNASMigrationDone(userId)) {
+ resetDefaultFromConfig();
+ setNASMigrationDone(userId);
+ }
Slog.d(TAG, "Approving default notification assistant for user " + userId);
setDefaultAssistantForUser(userId);
}
}
}
+ protected void resetDefaultFromConfig() {
+ clearDefaults();
+ loadDefaultsFromConfig();
+ }
+
+ protected void clearDefaults() {
+ mDefaultComponents.clear();
+ mDefaultPackages.clear();
+ }
+
@Override
protected void setPackageOrComponentEnabled(String pkgOrComponent, int userId,
boolean isPrimary, boolean enabled, boolean userSet) {
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 27e0ffc73d9d..91a66acf433d 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -978,7 +978,6 @@ public class LauncherAppsService extends SystemService {
// Flag for bubble to make behaviour match documentLaunchMode=always.
intents[0].addFlags(FLAG_ACTIVITY_NEW_DOCUMENT);
intents[0].addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
- intents[0].putExtra(Intent.EXTRA_IS_BUBBLED, true);
}
intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 8015063812e6..8b5abf3afe51 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -602,7 +602,7 @@ public class PackageManagerServiceUtils {
/** Returns true if standard APK Verity is enabled. */
static boolean isApkVerityEnabled() {
- return Build.VERSION.FIRST_SDK_INT >= Build.VERSION_CODES.R
+ return Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.R
|| SystemProperties.getInt("ro.apk_verity.mode", FSVERITY_DISABLED)
== FSVERITY_ENABLED;
}
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 19c56f82d7bf..e222df04022e 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -19,18 +19,33 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.Person;
+import android.app.appsearch.AppSearchManager;
+import android.app.appsearch.AppSearchResult;
import android.app.appsearch.AppSearchSession;
+import android.app.appsearch.GenericDocument;
+import android.app.appsearch.GetByUriRequest;
import android.app.appsearch.PackageIdentifier;
+import android.app.appsearch.PutDocumentsRequest;
+import android.app.appsearch.RemoveByUriRequest;
+import android.app.appsearch.ReportUsageRequest;
+import android.app.appsearch.SearchResult;
+import android.app.appsearch.SearchResults;
+import android.app.appsearch.SearchSpec;
+import android.app.appsearch.SetSchemaRequest;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.LocusId;
+import android.content.pm.AppSearchPerson;
+import android.content.pm.AppSearchShortcutInfo;
import android.content.pm.PackageInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.content.res.Resources;
import android.graphics.drawable.Icon;
+import android.os.Binder;
import android.os.PersistableBundle;
+import android.os.StrictMode;
import android.text.format.Formatter;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -41,10 +56,11 @@ import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
import android.util.Xml;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.infra.AndroidFuture;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.CollectionUtils;
+import com.android.internal.util.ConcurrentUtils;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import com.android.server.pm.ShortcutService.DumpFilter;
@@ -64,13 +80,17 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
+import java.util.function.Function;
import java.util.function.Predicate;
/**
@@ -95,6 +115,7 @@ class ShortcutPackage extends ShortcutPackageItem {
private static final String ATTR_NAME = "name";
private static final String ATTR_CALL_COUNT = "call-count";
private static final String ATTR_LAST_RESET = "last-reset";
+ private static final String ATTR_SCHEMA_VERSON = "schema-version";
private static final String ATTR_ID = "id";
private static final String ATTR_ACTIVITY = "activity";
private static final String ATTR_TITLE = "title";
@@ -137,9 +158,9 @@ class ShortcutPackage extends ShortcutPackageItem {
private static final String KEY_BITMAP_BYTES = "bitmapBytes";
/**
- * All the shortcuts from the package, keyed on IDs.
+ * An temp in-memory copy of shortcuts for this package that was loaded from xml, keyed on IDs.
*/
- private final ArrayMap<String, ShortcutInfo> mShortcuts = new ArrayMap<>();
+ final ArrayMap<String, ShortcutInfo> mShortcuts = new ArrayMap<>();
/**
* All the share targets from the package
@@ -167,8 +188,7 @@ class ShortcutPackage extends ShortcutPackageItem {
*/
private final Map<String, PackageIdentifier> mPackageIdentifiers = new ArrayMap<>(0);
- @GuardedBy("mLock")
- private AppSearchSession mAppSearchSession;
+ private boolean mIsInitilized;
private ShortcutPackage(ShortcutUser shortcutUser,
int packageUserId, String packageName, ShortcutPackageInfo spi) {
@@ -199,7 +219,9 @@ class ShortcutPackage extends ShortcutPackageItem {
}
public int getShortcutCount() {
- return mShortcuts.size();
+ final int[] count = new int[1];
+ forEachShortcut(si -> count[0]++);
+ return count[0];
}
@Override
@@ -213,17 +235,23 @@ class ShortcutPackage extends ShortcutPackageItem {
// - Unshadow all shortcuts.
// - Set disabled reason.
// - Disable if needed.
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- ShortcutInfo si = mShortcuts.valueAt(i);
- mutateShortcut(si.getId(), si, shortcut -> {
- shortcut.clearFlags(ShortcutInfo.FLAG_SHADOW);
-
- shortcut.setDisabledReason(restoreBlockReason);
- if (restoreBlockReason != ShortcutInfo.DISABLED_REASON_NOT_DISABLED) {
- shortcut.addFlags(ShortcutInfo.FLAG_DISABLED);
- }
- });
- }
+ final String query = String.format("%s:-%s AND %s:%s",
+ AppSearchShortcutInfo.KEY_FLAGS, ShortcutInfo.FLAG_SHADOW,
+ AppSearchShortcutInfo.KEY_DISABLED_REASON, restoreBlockReason);
+ forEachShortcutMutateIf(query, si -> {
+ if (restoreBlockReason == ShortcutInfo.DISABLED_REASON_NOT_DISABLED
+ && !si.hasFlags(ShortcutInfo.FLAG_SHADOW)
+ && si.getDisabledReason() == restoreBlockReason) {
+ return false;
+ }
+ si.clearFlags(ShortcutInfo.FLAG_SHADOW);
+
+ si.setDisabledReason(restoreBlockReason);
+ if (restoreBlockReason != ShortcutInfo.DISABLED_REASON_NOT_DISABLED) {
+ si.addFlags(ShortcutInfo.FLAG_DISABLED);
+ }
+ return true;
+ });
// Because some launchers may not have been restored (e.g. allowBackup=false),
// we need to re-calculate the pinned shortcuts.
refreshPinnedFlags();
@@ -233,8 +261,10 @@ class ShortcutPackage extends ShortcutPackageItem {
* Note this does *not* provide a correct view to the calling launcher.
*/
@Nullable
- public ShortcutInfo findShortcutById(String id) {
- return mShortcuts.get(id);
+ public ShortcutInfo findShortcutById(@Nullable final String id) {
+ if (id == null) return null;
+ final List<ShortcutInfo> ret = getShortcutById(Collections.singleton(id));
+ return ret.isEmpty() ? null : ret.get(0);
}
public boolean isShortcutExistsAndInvisibleToPublisher(String id) {
@@ -300,8 +330,9 @@ class ShortcutPackage extends ShortcutPackageItem {
* Delete a shortcut by ID. This will *always* remove it even if it's immutable or invisible.
*/
private ShortcutInfo forceDeleteShortcutInner(@NonNull String id) {
- final ShortcutInfo shortcut = mShortcuts.remove(id);
+ final ShortcutInfo shortcut = findShortcutById(id);
if (shortcut != null) {
+ removeShortcut(id);
mShortcutUser.mService.removeIconLocked(shortcut);
shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_PINNED
| ShortcutInfo.FLAG_MANIFEST | ShortcutInfo.FLAG_CACHED_ALL);
@@ -321,7 +352,7 @@ class ShortcutPackage extends ShortcutPackageItem {
// Extract Icon and update the icon res ID and the bitmap path.
s.saveIconAndFixUpShortcutLocked(newShortcut);
s.fixUpShortcutResourceNamesAndValues(newShortcut);
- mShortcuts.put(newShortcut.getId(), newShortcut);
+ saveShortcut(newShortcut);
}
/**
@@ -410,6 +441,15 @@ class ShortcutPackage extends ShortcutPackageItem {
}
forceReplaceShortcutInner(newShortcut);
+ mShortcutUser.mService.injectPostToHandler(() -> awaitInAppSearch("reportUsage",
+ session -> {
+ final AndroidFuture<Boolean> future = new AndroidFuture<>();
+ session.reportUsage(
+ new ReportUsageRequest.Builder(getPackageName())
+ .setUri(newShortcut.getId()).build(),
+ mShortcutUser.mExecutor, result -> future.complete(result.isSuccess()));
+ return future;
+ }));
return deleted;
}
@@ -419,19 +459,17 @@ class ShortcutPackage extends ShortcutPackageItem {
* @return List of removed shortcuts.
*/
private List<ShortcutInfo> removeOrphans() {
- List<ShortcutInfo> removeList = null;
-
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- final ShortcutInfo si = mShortcuts.valueAt(i);
-
- if (si.isAlive()) continue;
-
- if (removeList == null) {
- removeList = new ArrayList<>();
- }
+ final List<ShortcutInfo> removeList = new ArrayList<>(1);
+ final String query = String.format("%s OR %s OR %s OR %s",
+ AppSearchShortcutInfo.QUERY_IS_PINNED,
+ AppSearchShortcutInfo.QUERY_IS_DYNAMIC,
+ AppSearchShortcutInfo.QUERY_IS_MANIFEST,
+ AppSearchShortcutInfo.QUERY_IS_CACHED);
+ forEachShortcut(query, si -> {
+ if (si.isAlive()) return;
removeList.add(si);
- }
- if (removeList != null) {
+ });
+ if (!removeList.isEmpty()) {
for (int i = removeList.size() - 1; i >= 0; i--) {
forceDeleteShortcutInner(removeList.get(i).getId());
}
@@ -447,21 +485,27 @@ class ShortcutPackage extends ShortcutPackageItem {
*/
public List<ShortcutInfo> deleteAllDynamicShortcuts(boolean ignoreInvisible) {
final long now = mShortcutUser.mService.injectCurrentTimeMillis();
-
- boolean changed = false;
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- final ShortcutInfo si = mShortcuts.valueAt(i);
+ final String query;
+ if (!ignoreInvisible) {
+ query = AppSearchShortcutInfo.QUERY_IS_DYNAMIC;
+ } else {
+ query = String.format("%s %s",
+ AppSearchShortcutInfo.QUERY_IS_DYNAMIC,
+ AppSearchShortcutInfo.QUERY_IS_VISIBLE_TO_PUBLISHER);
+ }
+ final boolean[] changed = new boolean[1];
+ forEachShortcutMutateIf(query, si -> {
if (si.isDynamic() && (!ignoreInvisible || si.isVisibleToPublisher())) {
- changed = true;
+ changed[0] = true;
- mutateShortcut(si.getId(), si, shortcut -> {
- shortcut.setTimestamp(now);
- shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC);
- shortcut.setRank(0); // It may still be pinned, so clear the rank.
- });
+ si.setTimestamp(now);
+ si.clearFlags(ShortcutInfo.FLAG_DYNAMIC);
+ si.setRank(0); // It may still be pinned, so clear the rank.
+ return true;
}
- }
- if (changed) {
+ return false;
+ });
+ if (changed[0]) {
return removeOrphans();
}
return null;
@@ -606,45 +650,32 @@ class ShortcutPackage extends ShortcutPackageItem {
* <p>Then remove all shortcuts that are not dynamic and no longer pinned either.
*/
public void refreshPinnedFlags() {
- final List<ShortcutInfo> shortcuts = new ArrayList<>(mShortcuts.values());
- final Map<String, ShortcutInfo> shortcutMap = new ArrayMap<>(shortcuts.size());
- for (ShortcutInfo si : shortcuts) {
- shortcutMap.put(si.getId(), si);
- }
final Set<String> pinnedShortcuts = new ArraySet<>();
- // First, for the pinned set for each launcher, keep track of their id one by one.
+ // First, gather the pinned set from each launcher.
mShortcutUser.forAllLaunchers(launcherShortcuts -> {
final ArraySet<String> pinned = launcherShortcuts.getPinnedShortcutIds(
getPackageName(), getPackageUserId());
if (pinned == null || pinned.size() == 0) {
return;
}
- for (int i = pinned.size() - 1; i >= 0; i--) {
- final String id = pinned.valueAt(i);
- final ShortcutInfo si = shortcutMap.get(id);
- if (si == null) {
- // This happens if a launcher pinned shortcuts from this package, then backup&
- // restored, but this package doesn't allow backing up.
- // In that case the launcher ends up having a dangling pinned shortcuts.
- // That's fine, when the launcher is restored, we'll fix it.
- continue;
- }
- pinnedShortcuts.add(si.getId());
- }
+ pinnedShortcuts.addAll(pinned);
});
- // Then, update the pinned state if necessary
- for (int i = shortcuts.size() - 1; i >= 0; i--) {
- final ShortcutInfo si = shortcuts.get(i);
- if (pinnedShortcuts.contains(si.getId()) && !si.isPinned()) {
- mutateShortcut(si.getId(), si,
- shortcut -> shortcut.addFlags(ShortcutInfo.FLAG_PINNED));
+ // Then, update the pinned state if necessary.
+ final List<ShortcutInfo> pinned = getShortcutById(pinnedShortcuts);
+ pinned.forEach(si -> {
+ if (!si.isPinned()) {
+ si.addFlags(ShortcutInfo.FLAG_PINNED);
}
+ });
+ saveShortcut(pinned);
+ forEachShortcutMutateIf(AppSearchShortcutInfo.QUERY_IS_PINNED, si -> {
if (!pinnedShortcuts.contains(si.getId()) && si.isPinned()) {
- mutateShortcut(si.getId(), si, shortcut ->
- shortcut.clearFlags(ShortcutInfo.FLAG_PINNED));
+ si.clearFlags(ShortcutInfo.FLAG_PINNED);
+ return true;
}
- }
+ return false;
+ });
// Lastly, remove the ones that are no longer pinned, cached nor dynamic.
removeOrphans();
@@ -734,9 +765,9 @@ class ShortcutPackage extends ShortcutPackageItem {
/**
* Find all shortcuts that match {@code query}.
*/
- public void findAll(@NonNull List<ShortcutInfo> result,
- @Nullable Predicate<ShortcutInfo> query, int cloneFlag) {
- findAll(result, query, cloneFlag, null, 0, /*getPinnedByAnyLauncher=*/ false);
+ public void findAll(@NonNull List<ShortcutInfo> result, @Nullable String query,
+ @Nullable Predicate<ShortcutInfo> filter, int cloneFlag) {
+ findAll(result, query, filter, cloneFlag, null, 0, /*getPinnedByAnyLauncher=*/ false);
}
/**
@@ -747,7 +778,7 @@ class ShortcutPackage extends ShortcutPackageItem {
* adjusted for the caller too.
*/
public void findAll(@NonNull List<ShortcutInfo> result,
- @Nullable Predicate<ShortcutInfo> query, int cloneFlag,
+ @Nullable String query, @Nullable Predicate<ShortcutInfo> filter, int cloneFlag,
@Nullable String callingLauncher, int launcherUserId, boolean getPinnedByAnyLauncher) {
if (getPackageInfo().isShadow()) {
// Restored and the app not installed yet, so don't return any.
@@ -759,38 +790,101 @@ class ShortcutPackage extends ShortcutPackageItem {
final ArraySet<String> pinnedByCallerSet = (callingLauncher == null) ? null
: s.getLauncherShortcutsLocked(callingLauncher, getPackageUserId(), launcherUserId)
.getPinnedShortcutIds(getPackageName(), getPackageUserId());
+ forEachShortcut(query == null ? "" : query, si ->
+ filter(result, filter, cloneFlag, callingLauncher, pinnedByCallerSet,
+ getPinnedByAnyLauncher, si));
+ }
- for (int i = 0; i < mShortcuts.size(); i++) {
- final ShortcutInfo si = mShortcuts.valueAt(i);
- // Need to adjust PINNED flag depending on the caller.
- // Basically if the caller is a launcher (callingLauncher != null) and the launcher
- // isn't pinning it, then we need to clear PINNED for this caller.
- final boolean isPinnedByCaller = (callingLauncher == null)
- || ((pinnedByCallerSet != null) && pinnedByCallerSet.contains(si.getId()));
-
- if (!getPinnedByAnyLauncher) {
- if (si.isFloating() && !si.isCached()) {
- if (!isPinnedByCaller) {
- continue;
- }
- }
- }
- final ShortcutInfo clone = si.clone(cloneFlag);
+ /**
+ * Find all shortcuts that has id matching {@code ids}.
+ */
+ public void findAllByIds(@NonNull final List<ShortcutInfo> result,
+ @NonNull final Collection<String> ids, @Nullable final Predicate<ShortcutInfo> filter,
+ final int cloneFlag) {
+ findAllByIds(result, ids, filter, cloneFlag, null, 0, /*getPinnedByAnyLauncher=*/ false);
+ }
+
+ /**
+ * Find all shortcuts that has id matching {@code ids}.
+ *
+ * This will also provide a "view" for each launcher -- a non-dynamic shortcut that's not pinned
+ * by the calling launcher will not be included in the result, and also "isPinned" will be
+ * adjusted for the caller too.
+ */
+ public void findAllByIds(@NonNull List<ShortcutInfo> result,
+ @NonNull final Collection<String> ids, @Nullable final Predicate<ShortcutInfo> query,
+ int cloneFlag, @Nullable String callingLauncher, int launcherUserId,
+ boolean getPinnedByAnyLauncher) {
+ if (getPackageInfo().isShadow()) {
+ // Restored and the app not installed yet, so don't return any.
+ return;
+ }
+ final ShortcutService s = mShortcutUser.mService;
+
+ // Set of pinned shortcuts by the calling launcher.
+ final ArraySet<String> pinnedByCallerSet = (callingLauncher == null) ? null
+ : s.getLauncherShortcutsLocked(callingLauncher, getPackageUserId(), launcherUserId)
+ .getPinnedShortcutIds(getPackageName(), getPackageUserId());
+ final List<ShortcutInfo> shortcuts = getShortcutById(ids);
+ for (ShortcutInfo si : shortcuts) {
+ filter(result, query, cloneFlag, callingLauncher, pinnedByCallerSet,
+ getPinnedByAnyLauncher, si);
+ }
+ }
- // Fix up isPinned for the caller. Note we need to do it before the "test" callback,
- // since it may check isPinned.
- // However, if getPinnedByAnyLauncher is set, we do it after the test.
- if (!getPinnedByAnyLauncher) {
+ /**
+ * Find all pinned shortcuts that match {@code query}.
+ */
+ public void findAllPinned(@NonNull List<ShortcutInfo> result,
+ @Nullable Predicate<ShortcutInfo> query, int cloneFlag,
+ @Nullable String callingLauncher, int launcherUserId, boolean getPinnedByAnyLauncher) {
+ if (getPackageInfo().isShadow()) {
+ // Restored and the app not installed yet, so don't return any.
+ return;
+ }
+ final ShortcutService s = mShortcutUser.mService;
+
+ // Set of pinned shortcuts by the calling launcher.
+ final ArraySet<String> pinnedByCallerSet = (callingLauncher == null) ? null
+ : s.getLauncherShortcutsLocked(callingLauncher, getPackageUserId(), launcherUserId)
+ .getPinnedShortcutIds(getPackageName(), getPackageUserId());
+ mShortcuts.values().forEach(si -> filter(result, query, cloneFlag, callingLauncher,
+ pinnedByCallerSet, getPinnedByAnyLauncher, si));
+ }
+
+ private void filter(@NonNull final List<ShortcutInfo> result,
+ @Nullable final Predicate<ShortcutInfo> query, final int cloneFlag,
+ @Nullable final String callingLauncher,
+ @NonNull final ArraySet<String> pinnedByCallerSet,
+ final boolean getPinnedByAnyLauncher, @NonNull final ShortcutInfo si) {
+ // Need to adjust PINNED flag depending on the caller.
+ // Basically if the caller is a launcher (callingLauncher != null) and the launcher
+ // isn't pinning it, then we need to clear PINNED for this caller.
+ final boolean isPinnedByCaller = (callingLauncher == null)
+ || ((pinnedByCallerSet != null) && pinnedByCallerSet.contains(si.getId()));
+
+ if (!getPinnedByAnyLauncher) {
+ if (si.isFloating() && !si.isCached()) {
if (!isPinnedByCaller) {
- clone.clearFlags(ShortcutInfo.FLAG_PINNED);
+ return;
}
}
- if (query == null || query.test(clone)) {
- if (!isPinnedByCaller) {
- clone.clearFlags(ShortcutInfo.FLAG_PINNED);
- }
- result.add(clone);
+ }
+ final ShortcutInfo clone = si.clone(cloneFlag);
+
+ // Fix up isPinned for the caller. Note we need to do it before the "test" callback,
+ // since it may check isPinned.
+ // However, if getPinnedByAnyLauncher is set, we do it after the test.
+ if (!getPinnedByAnyLauncher) {
+ if (!isPinnedByCaller) {
+ clone.clearFlags(ShortcutInfo.FLAG_PINNED);
+ }
+ }
+ if (query == null || query.test(clone)) {
+ if (!isPinnedByCaller) {
+ clone.clearFlags(ShortcutInfo.FLAG_PINNED);
}
+ result.add(clone);
}
}
@@ -822,8 +916,8 @@ class ShortcutPackage extends ShortcutPackageItem {
// Get the list of all dynamic shortcuts in this package.
final ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
- findAll(shortcuts, ShortcutInfo::isNonManifestVisible,
- ShortcutInfo.CLONE_REMOVE_FOR_APP_PREDICTION);
+ findAll(shortcuts, AppSearchShortcutInfo.QUERY_IS_NON_MANIFEST_VISIBLE,
+ ShortcutInfo::isNonManifestVisible, ShortcutInfo.CLONE_REMOVE_FOR_APP_PREDICTION);
final List<ShortcutManager.ShareShortcutInfo> result = new ArrayList<>();
for (int i = 0; i < shortcuts.size(); i++) {
@@ -861,14 +955,14 @@ class ShortcutPackage extends ShortcutPackageItem {
* the app's Xml resource.
*/
int getSharingShortcutCount() {
- if (mShortcuts.isEmpty() || mShareTargets.isEmpty()) {
+ if (getShortcutCount() == 0 || mShareTargets.isEmpty()) {
return 0;
}
// Get the list of all dynamic shortcuts in this package
final ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
- findAll(shortcuts, ShortcutInfo::isNonManifestVisible,
- ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
+ findAll(shortcuts, AppSearchShortcutInfo.QUERY_IS_NON_MANIFEST_VISIBLE,
+ ShortcutInfo::isNonManifestVisible, ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
int sharingShortcutCount = 0;
for (int i = 0; i < shortcuts.size(); i++) {
@@ -899,14 +993,12 @@ class ShortcutPackage extends ShortcutPackageItem {
* Return the filenames (excluding path names) of icon bitmap files from this package.
*/
public ArraySet<String> getUsedBitmapFiles() {
- final ArraySet<String> usedFiles = new ArraySet<>(mShortcuts.size());
-
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- final ShortcutInfo si = mShortcuts.valueAt(i);
+ final ArraySet<String> usedFiles = new ArraySet<>(1);
+ forEachShortcut(AppSearchShortcutInfo.QUERY_HAS_BITMAP_PATH, si -> {
if (si.getBitmapPath() != null) {
usedFiles.add(getFileName(si.getBitmapPath()));
}
- }
+ });
return usedFiles;
}
@@ -923,30 +1015,29 @@ class ShortcutPackage extends ShortcutPackageItem {
* @return false if any of the target activities are no longer enabled.
*/
private boolean areAllActivitiesStillEnabled() {
- if (mShortcuts.size() == 0) {
- return true;
- }
final ShortcutService s = mShortcutUser.mService;
// Normally the number of target activities is 1 or so, so no need to use a complex
// structure like a set.
final ArrayList<ComponentName> checked = new ArrayList<>(4);
+ final boolean[] reject = new boolean[1];
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- final ShortcutInfo si = mShortcuts.valueAt(i);
+ forEachShortcutStopWhen(si -> {
final ComponentName activity = si.getActivity();
if (checked.contains(activity)) {
- continue; // Already checked.
+ return false; // Already checked.
}
checked.add(activity);
if ((activity != null)
&& !s.injectIsActivityEnabledAndExported(activity, getOwnerUserId())) {
- return false;
+ reject[0] = true;
+ return true; // Found at least 1 activity is disabled, so skip the rest.
}
- }
- return true;
+ return false;
+ });
+ return !reject[0];
}
/**
@@ -1029,32 +1120,34 @@ class ShortcutPackage extends ShortcutPackageItem {
// See if there are any shortcuts that were prevented restoring because the app was of a
// lower version, and re-enable them.
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- final ShortcutInfo si = mShortcuts.valueAt(i);
- if (si.getDisabledReason() != ShortcutInfo.DISABLED_REASON_VERSION_LOWER) {
- continue;
- }
- if (getPackageInfo().getBackupSourceVersionCode() > newVersionCode) {
- if (ShortcutService.DEBUG) {
- Slog.d(TAG, String.format("Shortcut %s require version %s, still not restored.",
- si.getId(), getPackageInfo().getBackupSourceVersionCode()));
- }
- continue;
- }
- Slog.i(TAG, String.format("Restoring shortcut: %s", si.getId()));
- mutateShortcut(si.getId(), si, shortcut -> {
- shortcut.clearFlags(ShortcutInfo.FLAG_DISABLED);
- shortcut.setDisabledReason(ShortcutInfo.DISABLED_REASON_NOT_DISABLED);
- });
+ {
+ forEachShortcutMutateIf(
+ AppSearchShortcutInfo.QUERY_DISABLED_REASON_VERSION_LOWER, si -> {
+ if (si.getDisabledReason() != ShortcutInfo.DISABLED_REASON_VERSION_LOWER) {
+ return false;
+ }
+ if (getPackageInfo().getBackupSourceVersionCode() > newVersionCode) {
+ if (ShortcutService.DEBUG) {
+ Slog.d(TAG,
+ String.format(
+ "Shortcut %s require version %s, still not restored.",
+ si.getId(),
+ getPackageInfo().getBackupSourceVersionCode()));
+ }
+ return false;
+ }
+ Slog.i(TAG, String.format("Restoring shortcut: %s", si.getId()));
+ si.clearFlags(ShortcutInfo.FLAG_DISABLED);
+ si.setDisabledReason(ShortcutInfo.DISABLED_REASON_NOT_DISABLED);
+ return true;
+ });
}
// For existing shortcuts, update timestamps if they have any resources.
// Also check if shortcuts' activities are still main activities. Otherwise, disable them.
if (!isNewApp) {
- Resources publisherRes = null;
-
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- final ShortcutInfo si = mShortcuts.valueAt(i);
+ final Resources publisherRes = getPackageResources();
+ forEachShortcutMutateIf(si -> {
// Disable dynamic shortcuts whose target activity is gone.
if (si.isDynamic()) {
if (si.getActivity() == null) {
@@ -1067,33 +1160,26 @@ class ShortcutPackage extends ShortcutPackageItem {
getPackageName(), si.getId()));
if (disableDynamicWithId(si.getId(), /*ignoreInvisible*/ false,
ShortcutInfo.DISABLED_REASON_APP_CHANGED) != null) {
- continue; // Actually removed.
+ return false; // Actually removed.
}
// Still pinned, so fall-through and possibly update the resources.
}
}
- if (si.hasAnyResources()) {
- if (publisherRes == null) {
- publisherRes = getPackageResources();
- if (publisherRes == null) {
- break; // Resources couldn't be loaded.
- }
- }
-
- final Resources res = publisherRes;
- mutateShortcut(si.getId(), si, shortcut -> {
- if (!shortcut.isOriginallyFromManifest()) {
- shortcut.lookupAndFillInResourceIds(res);
- }
+ if (!si.hasAnyResources() || publisherRes == null) {
+ return false;
+ }
- // If this shortcut is not from a manifest, then update all resource IDs
- // from resource names. (We don't allow resource strings for
- // non-manifest at the moment, but icons can still be resources.)
- shortcut.setTimestamp(s.injectCurrentTimeMillis());
- });
+ if (!si.isOriginallyFromManifest()) {
+ si.lookupAndFillInResourceIds(publisherRes);
}
- }
+
+ // If this shortcut is not from a manifest, then update all resource IDs
+ // from resource names. (We don't allow resource strings for
+ // non-manifest at the moment, but icons can still be resources.)
+ si.setTimestamp(s.injectCurrentTimeMillis());
+ return true;
+ });
}
// (Re-)publish manifest shortcut.
@@ -1119,17 +1205,12 @@ class ShortcutPackage extends ShortcutPackageItem {
boolean changed = false;
// Keep the previous IDs.
- ArraySet<String> toDisableList = null;
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- final ShortcutInfo si = mShortcuts.valueAt(i);
-
+ final ArraySet<String> toDisableList = new ArraySet<>(1);
+ forEachShortcut(AppSearchShortcutInfo.QUERY_IS_MANIFEST, si -> {
if (si.isManifestShortcut()) {
- if (toDisableList == null) {
- toDisableList = new ArraySet<>();
- }
toDisableList.add(si.getId());
}
- }
+ });
// Publish new ones.
if (newManifestShortcutList != null) {
@@ -1169,7 +1250,7 @@ class ShortcutPackage extends ShortcutPackageItem {
// regardless.
forceReplaceShortcutInner(newShortcut); // This will clean up the old one too.
- if (!newDisabled && toDisableList != null) {
+ if (!newDisabled && !toDisableList.isEmpty()) {
// Still alive, don't remove.
toDisableList.remove(id);
}
@@ -1177,7 +1258,7 @@ class ShortcutPackage extends ShortcutPackageItem {
}
// Disable the previous manifest shortcuts that are no longer in the manifest.
- if (toDisableList != null) {
+ if (!toDisableList.isEmpty()) {
if (ShortcutService.DEBUG) {
Slog.d(TAG, String.format(
"Package %s: disabling %d stale shortcuts", getPackageName(),
@@ -1266,25 +1347,21 @@ class ShortcutPackage extends ShortcutPackageItem {
private ArrayMap<ComponentName, ArrayList<ShortcutInfo>> sortShortcutsToActivities() {
final ArrayMap<ComponentName, ArrayList<ShortcutInfo>> activitiesToShortcuts
= new ArrayMap<>();
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- final ShortcutInfo si = mShortcuts.valueAt(i);
+ forEachShortcut(AppSearchShortcutInfo.QUERY_IS_NOT_FLOATING, si -> {
if (si.isFloating()) {
- continue; // Ignore floating shortcuts, which are not tied to any activities.
+ return; // Ignore floating shortcuts, which are not tied to any activities.
}
final ComponentName activity = si.getActivity();
if (activity == null) {
mShortcutUser.mService.wtf("null activity detected.");
- continue;
+ return;
}
- ArrayList<ShortcutInfo> list = activitiesToShortcuts.get(activity);
- if (list == null) {
- list = new ArrayList<>();
- activitiesToShortcuts.put(activity, list);
- }
+ ArrayList<ShortcutInfo> list = activitiesToShortcuts.computeIfAbsent(activity,
+ k -> new ArrayList<>());
list.add(si);
- }
+ });
return activitiesToShortcuts;
}
@@ -1320,14 +1397,20 @@ class ShortcutPackage extends ShortcutPackageItem {
// (If it's for update, then don't count dynamic shortcuts, since they'll be replaced
// anyway.)
final ArrayMap<ComponentName, Integer> counts = new ArrayMap<>(4);
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- final ShortcutInfo shortcut = mShortcuts.valueAt(i);
+ final String query;
+ if (operation != ShortcutService.OPERATION_SET) {
+ query = AppSearchShortcutInfo.QUERY_IS_MANIFEST + " OR "
+ + AppSearchShortcutInfo.QUERY_IS_DYNAMIC;
+ } else {
+ query = AppSearchShortcutInfo.QUERY_IS_MANIFEST;
+ }
+ forEachShortcut(query, shortcut -> {
if (shortcut.isManifestShortcut()) {
incrementCountForActivity(counts, shortcut.getActivity(), 1);
} else if (shortcut.isDynamic() && (operation != ShortcutService.OPERATION_SET)) {
incrementCountForActivity(counts, shortcut.getActivity(), 1);
}
- }
+ });
for (int i = newList.size() - 1; i >= 0; i--) {
final ShortcutInfo newShortcut = newList.get(i);
@@ -1340,7 +1423,7 @@ class ShortcutPackage extends ShortcutPackageItem {
continue; // Activity can be null for update.
}
- final ShortcutInfo original = mShortcuts.get(newShortcut.getId());
+ final ShortcutInfo original = findShortcutById(newShortcut.getId());
if (original == null) {
if (operation == ShortcutService.OPERATION_UPDATE) {
continue; // When updating, ignore if there's no target.
@@ -1379,31 +1462,17 @@ class ShortcutPackage extends ShortcutPackageItem {
public void resolveResourceStrings() {
final ShortcutService s = mShortcutUser.mService;
- List<ShortcutInfo> changedShortcuts = null;
-
- Resources publisherRes = null;
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- final ShortcutInfo si = mShortcuts.valueAt(i);
-
- if (si.hasStringResources()) {
- if (publisherRes == null) {
- publisherRes = getPackageResources();
- if (publisherRes == null) {
- break; // Resources couldn't be loaded.
- }
- }
+ final Resources publisherRes = getPackageResources();
+ final List<ShortcutInfo> changedShortcuts = new ArrayList<>(1);
- final Resources res = publisherRes;
- mutateShortcut(si.getId(), si, shortcut -> {
- shortcut.resolveResourceStrings(res);
- shortcut.setTimestamp(s.injectCurrentTimeMillis());
- });
-
- if (changedShortcuts == null) {
- changedShortcuts = new ArrayList<>(1);
- }
+ if (publisherRes != null) {
+ forEachShortcutMutateIf(AppSearchShortcutInfo.QUERY_HAS_STRING_RESOURCE, si -> {
+ if (!si.hasStringResources()) return false;
+ si.resolveResourceStrings(publisherRes);
+ si.setTimestamp(s.injectCurrentTimeMillis());
changedShortcuts.add(si);
- }
+ return true;
+ });
}
if (!CollectionUtils.isEmpty(changedShortcuts)) {
s.packageShortcutsChanged(getPackageName(), getPackageUserId(), changedShortcuts, null);
@@ -1412,10 +1481,7 @@ class ShortcutPackage extends ShortcutPackageItem {
/** Clears the implicit ranks for all shortcuts. */
public void clearAllImplicitRanks() {
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- final ShortcutInfo si = mShortcuts.valueAt(i);
- mutateShortcut(si.getId(), si, ShortcutInfo::clearImplicitRankAndRankChangedFlag);
- }
+ forEachShortcutMutate(ShortcutInfo::clearImplicitRankAndRankChangedFlag);
}
/**
@@ -1455,17 +1521,14 @@ class ShortcutPackage extends ShortcutPackageItem {
final long now = s.injectCurrentTimeMillis();
// First, clear ranks for floating shortcuts.
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- final ShortcutInfo si = mShortcuts.valueAt(i);
- if (si.isFloating()) {
- if (si.getRank() != 0) {
- mutateShortcut(si.getId(), si, shortcut -> {
- shortcut.setTimestamp(now);
- shortcut.setRank(0);
- });
- }
+ forEachShortcutMutateIf(AppSearchShortcutInfo.QUERY_IS_FLOATING_AND_HAS_RANK, si -> {
+ if (si.isFloating() && si.getRank() != 0) {
+ si.setTimestamp(now);
+ si.setRank(0);
+ return true;
}
- }
+ return false;
+ });
// Then adjust ranks. Ranks are unique for each activity, so we first need to sort
// shortcuts to each activity.
@@ -1507,13 +1570,14 @@ class ShortcutPackage extends ShortcutPackageItem {
/** @return true if there's any shortcuts that are not manifest shortcuts. */
public boolean hasNonManifestShortcuts() {
final boolean[] condition = new boolean[1];
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- final ShortcutInfo si = mShortcuts.valueAt(i);
+ forEachShortcutStopWhen(AppSearchShortcutInfo.QUERY_IS_NOT_MANIFEST, si -> {
if (!si.isDeclaredInManifest()) {
+ condition[0] = true;
return true;
}
- }
- return false;
+ return false;
+ });
+ return condition[0];
}
public void dump(@NonNull PrintWriter pw, @NonNull String prefix, DumpFilter filter) {
@@ -1553,11 +1617,8 @@ class ShortcutPackage extends ShortcutPackageItem {
pw.print(prefix);
pw.println(" Shortcuts:");
- long totalBitmapSize = 0;
- final ArrayMap<String, ShortcutInfo> shortcuts = mShortcuts;
- final int size = shortcuts.size();
- for (int i = 0; i < size; i++) {
- final ShortcutInfo si = shortcuts.valueAt(i);
+ final long[] totalBitmapSize = new long[1];
+ forEachShortcut(si -> {
pw.println(si.toDumpString(prefix + " "));
if (si.getBitmapPath() != null) {
final long len = new File(si.getBitmapPath()).length();
@@ -1566,15 +1627,15 @@ class ShortcutPackage extends ShortcutPackageItem {
pw.print("bitmap size=");
pw.println(len);
- totalBitmapSize += len;
+ totalBitmapSize[0] += len;
}
- }
+ });
pw.print(prefix);
pw.print(" ");
pw.print("Total bitmap size: ");
- pw.print(totalBitmapSize);
+ pw.print(totalBitmapSize[0]);
pw.print(" (");
- pw.print(Formatter.formatFileSize(mShortcutUser.mService.mContext, totalBitmapSize));
+ pw.print(Formatter.formatFileSize(mShortcutUser.mService.mContext, totalBitmapSize[0]));
pw.println(")");
}
@@ -1589,46 +1650,39 @@ class ShortcutPackage extends ShortcutPackageItem {
| (matchManifest ? ShortcutInfo.FLAG_MANIFEST : 0)
| (matchCached ? ShortcutInfo.FLAG_CACHED_ALL : 0);
- final ArrayMap<String, ShortcutInfo> shortcuts = mShortcuts;
- final int size = shortcuts.size();
- for (int i = 0; i < size; i++) {
- final ShortcutInfo si = shortcuts.valueAt(i);
+ forEachShortcut(si -> {
if ((si.getFlags() & shortcutFlags) != 0) {
pw.println(si.toDumpString(""));
}
- }
+ });
}
@Override
public JSONObject dumpCheckin(boolean clear) throws JSONException {
final JSONObject result = super.dumpCheckin(clear);
- int numDynamic = 0;
- int numPinned = 0;
- int numManifest = 0;
- int numBitmaps = 0;
- long totalBitmapSize = 0;
+ final int[] numDynamic = new int[1];
+ final int[] numPinned = new int[1];
+ final int[] numManifest = new int[1];
+ final int[] numBitmaps = new int[1];
+ final long[] totalBitmapSize = new long[1];
- final ArrayMap<String, ShortcutInfo> shortcuts = mShortcuts;
- final int size = shortcuts.size();
- for (int i = 0; i < size; i++) {
- final ShortcutInfo si = shortcuts.valueAt(i);
-
- if (si.isDynamic()) numDynamic++;
- if (si.isDeclaredInManifest()) numManifest++;
- if (si.isPinned()) numPinned++;
+ forEachShortcut(si -> {
+ if (si.isDynamic()) numDynamic[0]++;
+ if (si.isDeclaredInManifest()) numManifest[0]++;
+ if (si.isPinned()) numPinned[0]++;
if (si.getBitmapPath() != null) {
- numBitmaps++;
- totalBitmapSize += new File(si.getBitmapPath()).length();
+ numBitmaps[0]++;
+ totalBitmapSize[0] += new File(si.getBitmapPath()).length();
}
- }
+ });
- result.put(KEY_DYNAMIC, numDynamic);
- result.put(KEY_MANIFEST, numManifest);
- result.put(KEY_PINNED, numPinned);
- result.put(KEY_BITMAPS, numBitmaps);
- result.put(KEY_BITMAP_BYTES, totalBitmapSize);
+ result.put(KEY_DYNAMIC, numDynamic[0]);
+ result.put(KEY_MANIFEST, numManifest[0]);
+ result.put(KEY_PINNED, numPinned[0]);
+ result.put(KEY_BITMAPS, numBitmaps[0]);
+ result.put(KEY_BITMAP_BYTES, totalBitmapSize[0]);
// TODO Log update frequency too.
@@ -1638,10 +1692,10 @@ class ShortcutPackage extends ShortcutPackageItem {
@Override
public void saveToXml(@NonNull TypedXmlSerializer out, boolean forBackup)
throws IOException, XmlPullParserException {
- final int size = getShortcutCount();
+ final int size = mShortcuts.size();
final int shareTargetSize = mShareTargets.size();
- if (size == 0 && shareTargetSize == 0 && mApiCallCount == 0) {
+ if (size == 0 && shareTargetSize == 0 && mApiCallCount == 0 && getShortcutCount() == 0) {
return; // nothing to write.
}
@@ -1650,11 +1704,19 @@ class ShortcutPackage extends ShortcutPackageItem {
ShortcutService.writeAttr(out, ATTR_NAME, getPackageName());
ShortcutService.writeAttr(out, ATTR_CALL_COUNT, mApiCallCount);
ShortcutService.writeAttr(out, ATTR_LAST_RESET, mLastResetTime);
+ if (!forBackup) {
+ /**
+ * Schema version should not be included in the backup because:
+ * 1. Schemas in AppSearch are created from scratch on new device
+ * 2. Shortcuts are restored from xml file (as opposed to from AppSearch) on new device
+ */
+ ShortcutService.writeAttr(out, ATTR_SCHEMA_VERSON, (mIsInitilized)
+ ? AppSearchShortcutInfo.SCHEMA_VERSION : 0);
+ }
getPackageInfo().saveToXml(mShortcutUser.mService, out, forBackup);
for (int j = 0; j < size; j++) {
- saveShortcut(out, mShortcuts.valueAt(j), forBackup,
- getPackageInfo().isBackupAllowed());
+ saveShortcut(out, mShortcuts.valueAt(j), forBackup, getPackageInfo().isBackupAllowed());
}
if (!forBackup) {
@@ -1771,12 +1833,14 @@ class ShortcutPackage extends ShortcutPackageItem {
}
final Intent[] intentsNoExtras = si.getIntentsNoExtras();
final PersistableBundle[] intentsExtras = si.getIntentPersistableExtrases();
- final int numIntents = intentsNoExtras.length;
- for (int i = 0; i < numIntents; i++) {
- out.startTag(null, TAG_INTENT);
- ShortcutService.writeAttr(out, ATTR_INTENT_NO_EXTRA, intentsNoExtras[i]);
- ShortcutService.writeTagExtra(out, TAG_EXTRAS, intentsExtras[i]);
- out.endTag(null, TAG_INTENT);
+ if (intentsNoExtras != null && intentsExtras != null) {
+ final int numIntents = intentsNoExtras.length;
+ for (int i = 0; i < numIntents; i++) {
+ out.startTag(null, TAG_INTENT);
+ ShortcutService.writeAttr(out, ATTR_INTENT_NO_EXTRA, intentsNoExtras[i]);
+ ShortcutService.writeTagExtra(out, TAG_EXTRAS, intentsExtras[i]);
+ out.endTag(null, TAG_INTENT);
+ }
}
ShortcutService.writeTagExtra(out, TAG_EXTRAS, si.getExtras());
@@ -1839,6 +1903,7 @@ class ShortcutPackage extends ShortcutPackageItem {
final ShortcutPackage ret = new ShortcutPackage(shortcutUser,
shortcutUser.getUserId(), packageName);
+ ret.mIsInitilized = ShortcutService.parseIntAttribute(parser, ATTR_SCHEMA_VERSON, 0) > 0;
ret.mApiCallCount =
ShortcutService.parseIntAttribute(parser, ATTR_CALL_COUNT);
ret.mLastResetTime =
@@ -2060,7 +2125,9 @@ class ShortcutPackage extends ShortcutPackageItem {
@VisibleForTesting
List<ShortcutInfo> getAllShortcutsForTest() {
- return new ArrayList<>(mShortcuts.values());
+ final List<ShortcutInfo> ret = new ArrayList<>(1);
+ forEachShortcut(ret::add);
+ return ret;
}
@VisibleForTesting
@@ -2072,7 +2139,7 @@ class ShortcutPackage extends ShortcutPackageItem {
public void verifyStates() {
super.verifyStates();
- boolean failed = false;
+ final boolean[] failed = new boolean[1];
final ShortcutService s = mShortcutUser.mService;
@@ -2083,7 +2150,7 @@ class ShortcutPackage extends ShortcutPackageItem {
for (int outer = all.size() - 1; outer >= 0; outer--) {
final ArrayList<ShortcutInfo> list = all.valueAt(outer);
if (list.size() > mShortcutUser.mService.getMaxActivityShortcuts()) {
- failed = true;
+ failed[0] = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": activity " + all.keyAt(outer)
+ " has " + all.valueAt(outer).size() + " shortcuts.");
}
@@ -2103,61 +2170,60 @@ class ShortcutPackage extends ShortcutPackageItem {
}
// Verify each shortcut's status.
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- final ShortcutInfo si = mShortcuts.valueAt(i);
+ forEachShortcut(si -> {
if (!(si.isDeclaredInManifest() || si.isDynamic() || si.isPinned() || si.isCached())) {
- failed = true;
+ failed[0] = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " is not manifest, dynamic or pinned.");
}
if (si.isDeclaredInManifest() && si.isDynamic()) {
- failed = true;
+ failed[0] = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " is both dynamic and manifest at the same time.");
}
if (si.getActivity() == null && !si.isFloating()) {
- failed = true;
+ failed[0] = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " has null activity, but not floating.");
}
if ((si.isDynamic() || si.isManifestShortcut()) && !si.isEnabled()) {
- failed = true;
+ failed[0] = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " is not floating, but is disabled.");
}
if (si.isFloating() && si.getRank() != 0) {
- failed = true;
+ failed[0] = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " is floating, but has rank=" + si.getRank());
}
if (si.getIcon() != null) {
- failed = true;
+ failed[0] = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " still has an icon");
}
if (si.hasAdaptiveBitmap() && !(si.hasIconFile() || si.hasIconUri())) {
- failed = true;
+ failed[0] = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " has adaptive bitmap but was not saved to a file nor has icon uri.");
}
if (si.hasIconFile() && si.hasIconResource()) {
- failed = true;
+ failed[0] = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " has both resource and bitmap icons");
}
if (si.hasIconFile() && si.hasIconUri()) {
- failed = true;
+ failed[0] = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " has both url and bitmap icons");
}
if (si.hasIconUri() && si.hasIconResource()) {
- failed = true;
+ failed[0] = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " has both url and resource icons");
}
if (si.isEnabled()
!= (si.getDisabledReason() == ShortcutInfo.DISABLED_REASON_NOT_DISABLED)) {
- failed = true;
+ failed[0] = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " isEnabled() and getDisabledReason() disagree: "
+ si.isEnabled() + " vs " + si.getDisabledReason());
@@ -2165,18 +2231,18 @@ class ShortcutPackage extends ShortcutPackageItem {
if ((si.getDisabledReason() == ShortcutInfo.DISABLED_REASON_VERSION_LOWER)
&& (getPackageInfo().getBackupSourceVersionCode()
== ShortcutInfo.VERSION_CODE_UNKNOWN)) {
- failed = true;
+ failed[0] = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " RESTORED_VERSION_LOWER with no backup source version code.");
}
if (s.isDummyMainActivity(si.getActivity())) {
- failed = true;
+ failed[0] = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " has a dummy target activity");
}
- }
+ });
- if (failed) {
+ if (failed[0]) {
throw new IllegalStateException("See logcat for errors");
}
}
@@ -2187,6 +2253,8 @@ class ShortcutPackage extends ShortcutPackageItem {
} else {
mPackageIdentifiers.remove(packageName);
}
+ awaitInAppSearch(true, "Update visibility",
+ session -> AndroidFuture.completedFuture(true));
}
void mutateShortcut(@NonNull final String id, @Nullable final ShortcutInfo shortcut,
@@ -2196,23 +2264,309 @@ class ShortcutPackage extends ShortcutPackageItem {
synchronized (mLock) {
if (shortcut != null) {
transform.accept(shortcut);
+ }
+ final ShortcutInfo si = findShortcutById(id);
+ if (si == null) {
+ return;
+ }
+ transform.accept(si);
+ saveShortcut(si);
+ }
+ }
+
+ private void saveShortcut(@NonNull final ShortcutInfo... shortcuts) {
+ Objects.requireNonNull(shortcuts);
+ saveShortcut(Arrays.asList(shortcuts));
+ }
+
+ private void saveShortcut(@NonNull final Collection<ShortcutInfo> shortcuts) {
+ Objects.requireNonNull(shortcuts);
+ shortcuts.forEach(si -> {
+ if (si.isPinned()) {
+ mShortcuts.put(si.getId(), si);
} else {
- transform.accept(findShortcutById(id));
+ mShortcuts.remove(si.getId());
}
- // TODO: Load ShortcutInfo from AppSearch, apply transformation logic and save
+ });
+ saveToAppSearch(shortcuts);
+ }
+
+ private void saveToAppSearch(@NonNull final Collection<ShortcutInfo> shortcuts) {
+ Objects.requireNonNull(shortcuts);
+ if (shortcuts.isEmpty()) {
+ // No need to invoke AppSearch when there's nothing to save.
+ return;
}
+ awaitInAppSearch("Saving shortcuts", session -> {
+ final AndroidFuture<Boolean> future = new AndroidFuture<>();
+ session.put(new PutDocumentsRequest.Builder()
+ .addGenericDocuments(
+ AppSearchShortcutInfo.toGenericDocuments(shortcuts))
+ .build(),
+ mShortcutUser.mExecutor,
+ result -> {
+ if (!result.isSuccess()) {
+ for (AppSearchResult<Void> k : result.getFailures().values()) {
+ Slog.e(TAG, k.getErrorMessage());
+ }
+ future.completeExceptionally(new RuntimeException(
+ "Failed to save shortcuts"));
+ return;
+ }
+ future.complete(true);
+ });
+ return future;
+ });
}
/**
* Removes shortcuts from AppSearch.
*/
void removeShortcuts() {
+ awaitInAppSearch("Removing all shortcuts from " + getPackageName(), session -> {
+ final AndroidFuture<Boolean> future = new AndroidFuture<>();
+ session.remove("", getSearchSpec(), mShortcutUser.mExecutor, result -> {
+ if (!result.isSuccess()) {
+ future.completeExceptionally(
+ new RuntimeException(result.getErrorMessage()));
+ return;
+ }
+ future.complete(true);
+ });
+ return future;
+ });
+ }
+
+ private void removeShortcut(@NonNull final String id) {
+ Objects.requireNonNull(id);
+ mShortcuts.remove(id);
+ awaitInAppSearch("Removing shortcut with id=" + id, session -> {
+ final AndroidFuture<Boolean> future = new AndroidFuture<>();
+ session.remove(new RemoveByUriRequest.Builder(getPackageName()).addUris(id).build(),
+ mShortcutUser.mExecutor, result -> {
+ if (!result.isSuccess()) {
+ final Map<String, AppSearchResult<Void>> failures =
+ result.getFailures();
+ for (String key : failures.keySet()) {
+ Slog.e(TAG, "Failed deleting " + key + ", error message:"
+ + failures.get(key).getErrorMessage());
+ }
+ future.completeExceptionally(new RuntimeException(
+ "Failed to delete shortcut: " + id));
+ return;
+ }
+ future.complete(true);
+ });
+ return future;
+ });
+ }
+
+ @NonNull
+ private List<ShortcutInfo> getShortcutById(@NonNull final Collection<String> ids) {
+ final List<String> shortcutIds = new ArrayList<>(1);
+ for (String id : ids) {
+ if (id != null) {
+ shortcutIds.add(id);
+ }
+ }
+ return awaitInAppSearch("Getting shortcut by id", session -> {
+ final AndroidFuture<List<ShortcutInfo>> future = new AndroidFuture<>();
+ session.getByUri(
+ new GetByUriRequest.Builder(getPackageName()).addUris(shortcutIds).build(),
+ mShortcutUser.mExecutor,
+ results -> {
+ final List<ShortcutInfo> ret = new ArrayList<>(1);
+ Map<String, GenericDocument> documents = results.getSuccesses();
+ for (GenericDocument doc : documents.values()) {
+ final ShortcutInfo info = new AppSearchShortcutInfo(doc)
+ .toShortcutInfo(mShortcutUser.getUserId());
+ ret.add(info);
+ }
+ future.complete(ret);
+ });
+ return future;
+ });
+ }
+
+ private void forEachShortcut(@NonNull final Consumer<ShortcutInfo> cb) {
+ forEachShortcut("", cb);
+ }
+
+ private void forEachShortcut(
+ @NonNull final String query, @NonNull final Consumer<ShortcutInfo> cb) {
+ forEachShortcutStopWhen(query, si -> {
+ cb.accept(si);
+ return false;
+ });
+ }
+
+ private void forEachShortcutMutate(@NonNull final Consumer<ShortcutInfo> cb) {
+ forEachShortcutMutateIf(si -> {
+ cb.accept(si);
+ return true;
+ });
+ }
+
+ private void forEachShortcutMutateIf(@NonNull final Function<ShortcutInfo, Boolean> cb) {
+ forEachShortcutMutateIf("", cb);
+ }
+
+ private void forEachShortcutMutateIf(@NonNull final String query,
+ @NonNull final Function<ShortcutInfo, Boolean> cb) {
+ final SearchResults res = awaitInAppSearch("Mutating shortcuts", session ->
+ AndroidFuture.completedFuture(session.search(query, getSearchSpec())));
+ if (res == null) return;
+ List<ShortcutInfo> shortcuts = getNextPage(res);
+ while (!shortcuts.isEmpty()) {
+ final List<ShortcutInfo> changed = new ArrayList<>(1);
+ for (ShortcutInfo si : shortcuts) {
+ if (cb.apply(si)) changed.add(si);
+ }
+ saveShortcut(changed);
+ shortcuts = getNextPage(res);
+ }
+ }
+
+ private void forEachShortcutStopWhen(
+ @NonNull final Function<ShortcutInfo, Boolean> cb) {
+ forEachShortcutStopWhen("", cb);
+ }
+
+ private void forEachShortcutStopWhen(
+ @NonNull final String query, @NonNull final Function<ShortcutInfo, Boolean> cb) {
+ final SearchResults res = awaitInAppSearch("Iterating shortcuts", session ->
+ AndroidFuture.completedFuture(session.search(query, getSearchSpec())));
+ if (res == null) return;
+ List<ShortcutInfo> shortcuts = getNextPage(res);
+ while (!shortcuts.isEmpty()) {
+ for (ShortcutInfo si : shortcuts) {
+ if (cb.apply(si)) return;
+ }
+ shortcuts = getNextPage(res);
+ }
+ }
+
+ private List<ShortcutInfo> getNextPage(@NonNull final SearchResults res) {
+ final AndroidFuture<List<ShortcutInfo>> future = new AndroidFuture<>();
+ final List<ShortcutInfo> ret = new ArrayList<>();
+ final long callingIdentity = Binder.clearCallingIdentity();
+ try {
+ res.getNextPage(mShortcutUser.mExecutor, nextPage -> {
+ if (!nextPage.isSuccess()) {
+ future.complete(ret);
+ return;
+ }
+ final List<SearchResult> results = nextPage.getResultValue();
+ if (results.isEmpty()) {
+ future.complete(ret);
+ return;
+ }
+ final List<ShortcutInfo> page = new ArrayList<>(results.size());
+ for (SearchResult result : results) {
+ final ShortcutInfo si = new AppSearchShortcutInfo(result.getGenericDocument())
+ .toShortcutInfo(mShortcutUser.getUserId());
+ page.add(si);
+ }
+ ret.addAll(page);
+ future.complete(ret);
+ });
+ return ConcurrentUtils.waitForFutureNoInterrupt(future,
+ "Getting next batch of shortcuts");
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentity);
+ }
+ }
+
+ @Nullable
+ private <T> T awaitInAppSearch(
+ @NonNull final String description,
+ @NonNull final Function<AppSearchSession, CompletableFuture<T>> cb) {
+ return awaitInAppSearch(false, description, cb);
+ }
+
+ @Nullable
+ private <T> T awaitInAppSearch(
+ final boolean forceReset,
+ @NonNull final String description,
+ @NonNull final Function<AppSearchSession, CompletableFuture<T>> cb) {
+ synchronized (mLock) {
+ final StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
+ final long callingIdentity = Binder.clearCallingIdentity();
+ final AppSearchManager.SearchContext searchContext =
+ new AppSearchManager.SearchContext.Builder(getPackageName()).build();
+ try (AppSearchSession session = ConcurrentUtils.waitForFutureNoInterrupt(
+ mShortcutUser.getAppSearch(searchContext), "Resetting app search")) {
+ StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
+ .detectAll()
+ .penaltyLog() // TODO: change this to penaltyDeath to fix the call-site
+ .build());
+ final boolean wasInitialized = mIsInitilized;
+ if (!wasInitialized || forceReset) {
+ ConcurrentUtils.waitForFutureNoInterrupt(
+ setupSchema(session), "Setting up schema");
+ }
+ mIsInitilized = true;
+ if (!wasInitialized) {
+ restoreParsedShortcuts(false);
+ }
+ return ConcurrentUtils.waitForFutureNoInterrupt(cb.apply(session), description);
+ } catch (Exception e) {
+ Slog.e(TAG, "Failed to initiate app search for shortcut package "
+ + getPackageName() + " user " + mShortcutUser.getUserId(), e);
+ return null;
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentity);
+ StrictMode.setThreadPolicy(oldPolicy);
+ }
+ }
+ }
+
+ @NonNull
+ private AndroidFuture<AppSearchSession> setupSchema(
+ @NonNull final AppSearchSession session) {
+ SetSchemaRequest.Builder schemaBuilder = new SetSchemaRequest.Builder()
+ .addSchemas(AppSearchPerson.SCHEMA, AppSearchShortcutInfo.SCHEMA);
+ for (PackageIdentifier pi : mPackageIdentifiers.values()) {
+ schemaBuilder = schemaBuilder
+ .setSchemaTypeVisibilityForPackage(
+ AppSearchPerson.SCHEMA_TYPE, true, pi)
+ .setSchemaTypeVisibilityForPackage(
+ AppSearchShortcutInfo.SCHEMA_TYPE, true, pi);
+ }
+ final AndroidFuture<AppSearchSession> future = new AndroidFuture<>();
+ session.setSchema(
+ schemaBuilder.build(), mShortcutUser.mExecutor, mShortcutUser.mExecutor, result -> {
+ if (!result.isSuccess()) {
+ future.completeExceptionally(
+ new IllegalArgumentException(result.getErrorMessage()));
+ return;
+ }
+ future.complete(session);
+ });
+ return future;
+ }
+
+ @NonNull
+ private SearchSpec getSearchSpec() {
+ return new SearchSpec.Builder()
+ .addFilterSchemas(AppSearchShortcutInfo.SCHEMA_TYPE)
+ .addFilterNamespaces(getPackageName())
+ .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+ .build();
}
/**
- * Merge/replace shortcuts parsed from xml file.
+ * Replace shortcuts parsed from xml file.
*/
- void restoreParsedShortcuts(final boolean replace) {
+ void restoreParsedShortcuts() {
+ restoreParsedShortcuts(true);
+ }
+
+ private void restoreParsedShortcuts(final boolean replace) {
+ if (replace) {
+ removeShortcuts();
+ }
+ saveToAppSearch(mShortcuts.values());
}
private boolean verifyRanksSequential(List<ShortcutInfo> list) {
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 8e999de80707..dcf730d4a0fd 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -39,6 +39,7 @@ import android.content.IntentSender;
import android.content.IntentSender.SendIntentException;
import android.content.LocusId;
import android.content.pm.ActivityInfo;
+import android.content.pm.AppSearchShortcutInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ComponentInfo;
import android.content.pm.IPackageManager;
@@ -1050,8 +1051,7 @@ public class ShortcutService extends IShortcutService.Stub {
file.failWrite(os);
}
- final ShortcutUser user = getUserShortcutsLocked(userId);
- user.logSharingShortcutStats(mMetricsLogger);
+ getUserShortcutsLocked(userId).logSharingShortcutStats(mMetricsLogger);
}
@GuardedBy("mLock")
@@ -1306,7 +1306,7 @@ public class ShortcutService extends IShortcutService.Stub {
mUsers.put(userId, userPackages);
// Also when a user's data is first accessed, scan all packages.
- checkPackageChanges(userId);
+ injectPostToHandler(() -> checkPackageChanges(userId));
}
return userPackages;
}
@@ -1934,7 +1934,8 @@ public class ShortcutService extends IShortcutService.Stub {
}
ArrayList<ShortcutInfo> cachedOrPinned = new ArrayList<>();
- ps.findAll(cachedOrPinned, (ShortcutInfo si) -> si.isVisibleToPublisher()
+ ps.findAll(cachedOrPinned, AppSearchShortcutInfo.QUERY_IS_VISIBLE_CACHED_OR_PINNED,
+ (ShortcutInfo si) -> si.isVisibleToPublisher()
&& si.isDynamic() && (si.isCached() || si.isPinned()),
ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
@@ -2431,8 +2432,9 @@ public class ShortcutService extends IShortcutService.Stub {
final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
// Dynamic shortcuts that are either cached or pinned will not get deleted.
- ps.findAll(changedShortcuts, (ShortcutInfo si) -> si.isVisibleToPublisher()
- && si.isDynamic() && (si.isCached() || si.isPinned()),
+ ps.findAll(changedShortcuts, AppSearchShortcutInfo.QUERY_IS_VISIBLE_CACHED_OR_PINNED,
+ (ShortcutInfo si) -> si.isVisibleToPublisher()
+ && si.isDynamic() && (si.isCached() || si.isPinned()),
ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
removedShortcuts = ps.deleteAllDynamicShortcuts(/*ignoreInvisible=*/ true);
@@ -2511,8 +2513,11 @@ public class ShortcutService extends IShortcutService.Stub {
| (matchManifest ? ShortcutInfo.FLAG_MANIFEST : 0)
| (matchCached ? ShortcutInfo.FLAG_CACHED_ALL : 0);
+ final String query = AppSearchShortcutInfo.QUERY_IS_VISIBLE_TO_PUBLISHER + " "
+ + createQuery(matchDynamic, matchPinned, matchManifest, matchCached);
+
callback.complete(getShortcutsWithQueryLocked(
- packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
+ packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR, query,
(ShortcutInfo si) ->
si.isVisibleToPublisher() && (si.getFlags() & shortcutFlags) != 0));
}
@@ -2588,12 +2593,13 @@ public class ShortcutService extends IShortcutService.Stub {
@GuardedBy("mLock")
private ParceledListSlice<ShortcutInfo> getShortcutsWithQueryLocked(@NonNull String packageName,
- @UserIdInt int userId, int cloneFlags, @NonNull Predicate<ShortcutInfo> query) {
+ @UserIdInt int userId, int cloneFlags, @NonNull final String query,
+ @NonNull Predicate<ShortcutInfo> filter) {
final ArrayList<ShortcutInfo> ret = new ArrayList<>();
final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
- ps.findAll(ret, query, cloneFlags);
+ ps.findAll(ret, query, filter, cloneFlags);
return new ParceledListSlice<>(setReturnedByServer(ret));
}
@@ -2851,6 +2857,28 @@ public class ShortcutService extends IShortcutService.Stub {
}
}
+ private String createQuery(final boolean matchDynamic, final boolean matchPinned,
+ final boolean matchManifest, final boolean matchCached) {
+
+ final List<String> queries = new ArrayList<>(1);
+ if (matchDynamic) {
+ queries.add(AppSearchShortcutInfo.QUERY_IS_DYNAMIC);
+ }
+ if (matchPinned) {
+ queries.add(AppSearchShortcutInfo.QUERY_IS_PINNED);
+ }
+ if (matchManifest) {
+ queries.add(AppSearchShortcutInfo.QUERY_IS_MANIFEST);
+ }
+ if (matchCached) {
+ queries.add(AppSearchShortcutInfo.QUERY_IS_CACHED);
+ }
+ if (queries.isEmpty()) {
+ return "";
+ }
+ return "(" + String.join(" OR ", queries) + ")";
+ }
+
/**
* Remove all the information associated with a package. This will really remove all the
* information, including the restore information (i.e. it'll remove packages even if they're
@@ -2963,18 +2991,12 @@ public class ShortcutService extends IShortcutService.Stub {
int callingPid, int callingUid) {
final ArraySet<String> ids = shortcutIds == null ? null
: new ArraySet<>(shortcutIds);
- final ArraySet<LocusId> locIds = locusIds == null ? null
- : new ArraySet<>(locusIds);
final ShortcutUser user = getUserShortcutsLocked(userId);
final ShortcutPackage p = user.getPackageShortcutsIfExists(packageName);
if (p == null) {
return; // No need to instantiate ShortcutPackage.
}
- final boolean matchDynamic = (queryFlags & ShortcutQuery.FLAG_MATCH_DYNAMIC) != 0;
- final boolean matchPinned = (queryFlags & ShortcutQuery.FLAG_MATCH_PINNED) != 0;
- final boolean matchManifest = (queryFlags & ShortcutQuery.FLAG_MATCH_MANIFEST) != 0;
- final boolean matchCached = (queryFlags & ShortcutQuery.FLAG_MATCH_CACHED) != 0;
final boolean canAccessAllShortcuts =
canSeeAnyPinnedShortcut(callingPackage, launcherUserId, callingPid, callingUid);
@@ -2982,38 +3004,73 @@ public class ShortcutService extends IShortcutService.Stub {
final boolean getPinnedByAnyLauncher =
canAccessAllShortcuts &&
((queryFlags & ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER) != 0);
+ queryFlags |= (getPinnedByAnyLauncher ? ShortcutQuery.FLAG_MATCH_PINNED : 0);
+
+ final boolean matchPinnedOnly =
+ ((queryFlags & ShortcutQuery.FLAG_MATCH_PINNED) != 0)
+ && ((queryFlags & ShortcutQuery.FLAG_MATCH_CACHED) == 0)
+ && ((queryFlags & ShortcutQuery.FLAG_MATCH_DYNAMIC) == 0)
+ && ((queryFlags & ShortcutQuery.FLAG_MATCH_MANIFEST) == 0);
+
+ final Predicate<ShortcutInfo> filter = getFilterFromQuery(ids, locusIds, changedSince,
+ componentName, queryFlags, getPinnedByAnyLauncher);
+ if (matchPinnedOnly) {
+ p.findAllPinned(ret, filter, cloneFlag, callingPackage, launcherUserId,
+ getPinnedByAnyLauncher);
+ } else if (ids != null && !ids.isEmpty()) {
+ p.findAllByIds(ret, ids, filter, cloneFlag, callingPackage, launcherUserId,
+ getPinnedByAnyLauncher);
+ } else {
+ final boolean matchDynamic = (queryFlags & ShortcutQuery.FLAG_MATCH_DYNAMIC) != 0;
+ final boolean matchPinned = (queryFlags & ShortcutQuery.FLAG_MATCH_PINNED) != 0;
+ final boolean matchManifest = (queryFlags & ShortcutQuery.FLAG_MATCH_MANIFEST) != 0;
+ final boolean matchCached = (queryFlags & ShortcutQuery.FLAG_MATCH_CACHED) != 0;
+ p.findAll(ret, createQuery(matchDynamic, matchPinned, matchManifest, matchCached),
+ filter, cloneFlag, callingPackage, launcherUserId, getPinnedByAnyLauncher);
+ }
+ }
- p.findAll(ret,
- (ShortcutInfo si) -> {
- if (si.getLastChangedTimestamp() < changedSince) {
- return false;
- }
- if (ids != null && !ids.contains(si.getId())) {
- return false;
- }
- if (locIds != null && !locIds.contains(si.getLocusId())) {
- return false;
- }
- if (componentName != null) {
- if (si.getActivity() != null
- && !si.getActivity().equals(componentName)) {
- return false;
- }
- }
- if (matchDynamic && si.isDynamic()) {
- return true;
- }
- if ((matchPinned || getPinnedByAnyLauncher) && si.isPinned()) {
- return true;
- }
- if (matchManifest && si.isDeclaredInManifest()) {
- return true;
- }
- if (matchCached && si.isCached()) {
- return true;
- }
+ private Predicate<ShortcutInfo> getFilterFromQuery(@Nullable ArraySet<String> ids,
+ @Nullable List<LocusId> locusIds, long changedSince,
+ @Nullable ComponentName componentName, int queryFlags,
+ boolean getPinnedByAnyLauncher) {
+ final ArraySet<LocusId> locIds = locusIds == null ? null
+ : new ArraySet<>(locusIds);
+
+ final boolean matchDynamic = (queryFlags & ShortcutQuery.FLAG_MATCH_DYNAMIC) != 0;
+ final boolean matchPinned = (queryFlags & ShortcutQuery.FLAG_MATCH_PINNED) != 0;
+ final boolean matchManifest = (queryFlags & ShortcutQuery.FLAG_MATCH_MANIFEST) != 0;
+ final boolean matchCached = (queryFlags & ShortcutQuery.FLAG_MATCH_CACHED) != 0;
+ return si -> {
+ if (si.getLastChangedTimestamp() < changedSince) {
+ return false;
+ }
+ if (ids != null && !ids.contains(si.getId())) {
+ return false;
+ }
+ if (locIds != null && !locIds.contains(si.getLocusId())) {
+ return false;
+ }
+ if (componentName != null) {
+ if (si.getActivity() != null
+ && !si.getActivity().equals(componentName)) {
return false;
- }, cloneFlag, callingPackage, launcherUserId, getPinnedByAnyLauncher);
+ }
+ }
+ if (matchDynamic && si.isDynamic()) {
+ return true;
+ }
+ if ((matchPinned || getPinnedByAnyLauncher) && si.isPinned()) {
+ return true;
+ }
+ if (matchManifest && si.isDeclaredInManifest()) {
+ return true;
+ }
+ if (matchCached && si.isCached()) {
+ return true;
+ }
+ return false;
+ };
}
@Override
@@ -3054,7 +3111,7 @@ public class ShortcutService extends IShortcutService.Stub {
}
final ArrayList<ShortcutInfo> list = new ArrayList<>(1);
- p.findAll(list,
+ p.findAllByIds(list, Collections.singletonList(shortcutId),
(ShortcutInfo si) -> shortcutId.equals(si.getId()),
/* clone flags=*/ 0, callingPackage, launcherUserId, getPinnedByAnyLauncher);
return list.size() == 0 ? null : list.get(0);
@@ -3084,9 +3141,11 @@ public class ShortcutService extends IShortcutService.Stub {
if (sp != null) {
// List the shortcuts that are pinned only, these will get removed.
removedShortcuts = new ArrayList<>();
- sp.findAll(removedShortcuts, (ShortcutInfo si) -> si.isVisibleToPublisher()
- && si.isPinned() && !si.isCached() && !si.isDynamic()
- && !si.isDeclaredInManifest(), ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO,
+ sp.findAll(removedShortcuts, AppSearchShortcutInfo.QUERY_IS_VISIBLE_PINNED_ONLY,
+ (ShortcutInfo si) -> si.isVisibleToPublisher()
+ && si.isPinned() && !si.isCached() && !si.isDynamic()
+ && !si.isDeclaredInManifest(),
+ ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO,
callingPackage, launcherUserId, false);
}
// Get list of shortcuts that will get unpinned.
@@ -5081,6 +5140,17 @@ public class ShortcutService extends IShortcutService.Stub {
}
@VisibleForTesting
+ void updatePackageShortcutForTest(String packageName, String shortcutId, int userId,
+ Consumer<ShortcutInfo> cb) {
+ synchronized (mLock) {
+ final ShortcutPackage pkg = getPackageShortcutForTest(packageName, userId);
+ if (pkg == null) return;
+
+ pkg.mutateShortcut(shortcutId, null, cb);
+ }
+ }
+
+ @VisibleForTesting
ShortcutLauncher getLauncherShortcutForTest(String packageName, int userId) {
synchronized (mLock) {
final ShortcutUser user = mUsers.get(userId);
@@ -5162,7 +5232,7 @@ public class ShortcutService extends IShortcutService.Stub {
}
List<ShortcutInfo> result = new ArrayList<>();
- ps.findAll(result, (ShortcutInfo si) -> resultIds.contains(si.getId()),
+ ps.findAllByIds(result, resultIds, (ShortcutInfo si) -> resultIds.contains(si.getId()),
ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
return result;
}
diff --git a/services/core/java/com/android/server/pm/ShortcutUser.java b/services/core/java/com/android/server/pm/ShortcutUser.java
index 5f0aa03cac59..069944d955ea 100644
--- a/services/core/java/com/android/server/pm/ShortcutUser.java
+++ b/services/core/java/com/android/server/pm/ShortcutUser.java
@@ -457,7 +457,6 @@ class ShortcutUser {
case ShortcutPackage.TAG_ROOT: {
final ShortcutPackage shortcuts = ShortcutPackage.loadFromXml(
s, ret, parser, fromBackup);
- shortcuts.restoreParsedShortcuts(false);
// Don't use addShortcut(), we don't need to save the icon.
ret.mPackages.put(shortcuts.getPackageName(), shortcuts);
@@ -492,7 +491,6 @@ class ShortcutUser {
final ShortcutPackage sp = ShortcutPackage.loadFromFile(s, ret, f, fromBackup);
if (sp != null) {
ret.mPackages.put(sp.getPackageName(), sp);
- sp.restoreParsedShortcuts(false);
}
});
@@ -575,7 +573,7 @@ class ShortcutUser {
Log.w(TAG, "Shortcuts for package " + sp.getPackageName() + " are being restored."
+ " Existing non-manifeset shortcuts will be overwritten.");
}
- sp.restoreParsedShortcuts(true);
+ sp.restoreParsedShortcuts();
addPackage(sp);
restoredPackages[0]++;
restoredShortcuts[0] += sp.getShortcutCount();
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index c7789eecc68f..5b333e15fe67 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -273,6 +273,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final int VERY_LONG_PRESS_POWER_NOTHING = 0;
static final int VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
+ // must match: config_keyChordPowerVolumeUp in config.xml
+ static final int POWER_VOLUME_UP_BEHAVIOR_NOTHING = 0;
+ static final int POWER_VOLUME_UP_BEHAVIOR_MUTE = 1;
+ static final int POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS = 2;
+
// must match: config_doublePressOnPowerBehavior in config.xml
static final int MULTI_PRESS_POWER_NOTHING = 0;
static final int MULTI_PRESS_POWER_THEATER_MODE = 1;
@@ -405,6 +410,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private boolean mEnableCarDockHomeCapture = true;
boolean mBootMessageNeedsHiding;
+ volatile boolean mBootAnimationDismissable;
private KeyguardServiceDelegate mKeyguardDelegate;
private boolean mKeyguardBound;
final Runnable mWindowManagerDrawCallback = new Runnable() {
@@ -488,6 +494,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
int mLongPressOnBackBehavior;
int mShortPressOnSleepBehavior;
int mShortPressOnWindowBehavior;
+ int mPowerVolUpBehavior;
boolean mHasSoftInput = false;
boolean mHapticTextHandleEnabled;
boolean mUseTvRouting;
@@ -728,6 +735,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Settings.Global.POWER_BUTTON_VERY_LONG_PRESS), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.KEY_CHORD_POWER_VOLUME_UP), false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE), false, this,
UserHandle.USER_ALL);
updateSettings();
@@ -1267,6 +1277,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
}
+ private void cancelGlobalActionsAction() {
+ mHandler.removeMessages(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS);
+ }
+
boolean isDeviceProvisioned() {
return Settings.Global.getInt(
mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0;
@@ -1835,20 +1849,48 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
});
+ // Volume up + power can either be the "ringer toggle chord" or as another way to
+ // launch GlobalActions. This behavior can change at runtime so we must check behavior
+ // inside the TwoKeysCombinationRule.
mKeyCombinationManager.addRule(
new TwoKeysCombinationRule(KEYCODE_VOLUME_UP, KEYCODE_POWER) {
@Override
boolean preCondition() {
- return mRingerToggleChord != VOLUME_HUSH_OFF;
+ switch (mPowerVolUpBehavior) {
+ case POWER_VOLUME_UP_BEHAVIOR_MUTE:
+ return mRingerToggleChord != VOLUME_HUSH_OFF;
+ default:
+ return true;
+ }
}
@Override
void execute() {
- mPowerKeyHandled = true;
- interceptRingerToggleChord();
+ switch (mPowerVolUpBehavior) {
+ case POWER_VOLUME_UP_BEHAVIOR_MUTE:
+ // no haptic feedback here since
+ interceptRingerToggleChord();
+ mPowerKeyHandled = true;
+ break;
+ case POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS:
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,
+ "Power + Volume Up - Global Actions");
+ showGlobalActions();
+ mPowerKeyHandled = true;
+ break;
+ default:
+ break;
+ }
}
@Override
void cancel() {
- cancelPendingRingerToggleChordAction();
+ switch (mPowerVolUpBehavior) {
+ case POWER_VOLUME_UP_BEHAVIOR_MUTE:
+ cancelPendingRingerToggleChordAction();
+ break;
+ case POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS:
+ cancelGlobalActionsAction();
+ break;
+ }
}
});
@@ -2054,6 +2096,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Settings.Global.POWER_BUTTON_VERY_LONG_PRESS,
mContext.getResources().getInteger(
com.android.internal.R.integer.config_veryLongPressOnPowerBehavior));
+ mPowerVolUpBehavior = Settings.Global.getInt(resolver,
+ Settings.Global.KEY_CHORD_POWER_VOLUME_UP,
+ mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_keyChordPowerVolumeUp));
}
if (updateRotation) {
updateRotation(true);
@@ -3408,8 +3454,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return interceptKeyBeforeQueueing(event, policyFlags);
}
+ // This could prevent some wrong state in multi-displays environment,
+ // the default display may turned off but interactive is true.
+ final boolean isDefaultDisplayOn = Display.isOnState(mDefaultDisplay.getState());
+ final boolean interactiveAndOn = interactive && isDefaultDisplayOn;
if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
- handleKeyGesture(event, interactive);
+ handleKeyGesture(event, interactiveAndOn);
}
// Enable haptics if down and virtual key without multiple repetitions. If this is a hard
@@ -3556,8 +3606,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Any activity on the power button stops the accessibility shortcut
result &= ~ACTION_PASS_TO_USER;
isWakeKey = false; // wake-up will be handled separately
- final boolean isDefaultDisplayOn = Display.isOnState(mDefaultDisplay.getState());
- final boolean interactiveAndOn = interactive && isDefaultDisplayOn;
if (down) {
interceptPowerKeyDown(event, interactiveAndOn);
} else {
@@ -4305,6 +4353,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
0 /* cookie */);
updateScreenOffSleepToken(false);
mDefaultDisplayPolicy.screenTurnedOn(screenOnListener);
+ mBootAnimationDismissable = false;
synchronized (mLock) {
if (mKeyguardDelegate != null && mKeyguardDelegate.hasKeyguard()) {
@@ -4379,6 +4428,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn", 0 /* cookie */);
+ enableScreen(listener, true /* report */);
+ }
+
+ private void enableScreen(ScreenOnListener listener, boolean report) {
final boolean enableScreen;
final boolean awake = mDefaultDisplayPolicy.isAwake();
synchronized (mLock) {
@@ -4396,17 +4449,19 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
- if (listener != null) {
- listener.onScreenOn();
- }
+ if (report) {
+ if (listener != null) {
+ listener.onScreenOn();
+ }
- for (int i = mScreenOnListeners.size() - 1; i >= 0; i--) {
- final ScreenOnListener screenOnListener = mScreenOnListeners.valueAt(i);
- if (screenOnListener != null) {
- screenOnListener.onScreenOn();
+ for (int i = mScreenOnListeners.size() - 1; i >= 0; i--) {
+ final ScreenOnListener screenOnListener = mScreenOnListeners.valueAt(i);
+ if (screenOnListener != null) {
+ screenOnListener.onScreenOn();
+ }
}
+ mScreenOnListeners.clear();
}
- mScreenOnListeners.clear();
if (enableScreen) {
try {
@@ -4614,13 +4669,28 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
startedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
finishedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
- screenTurningOn(DEFAULT_DISPLAY, mDefaultDisplayPolicy.getScreenOnListener());
- screenTurnedOn(DEFAULT_DISPLAY);
+
+ int defaultDisplayState = mDisplayManager.getDisplay(DEFAULT_DISPLAY).getState();
+ boolean defaultDisplayOn = defaultDisplayState == Display.STATE_ON;
+ boolean defaultScreenTurningOn = mDefaultDisplayPolicy.getScreenOnListener() != null;
+ if (defaultDisplayOn || defaultScreenTurningOn) {
+ // Now that system is booted, wait for keyguard and windows to be drawn before
+ // updating the orientation listener, stopping the boot animation and enabling screen.
+ screenTurningOn(DEFAULT_DISPLAY, mDefaultDisplayPolicy.getScreenOnListener());
+ screenTurnedOn(DEFAULT_DISPLAY);
+ } else {
+ // We're not turning the screen on, so don't wait for keyguard to be drawn
+ // to dismiss the boot animation and finish booting
+ mBootAnimationDismissable = true;
+ enableScreen(null, false /* report */);
+ }
}
@Override
public boolean canDismissBootAnimation() {
- return mDefaultDisplayPolicy.isKeyguardDrawComplete();
+ // Allow to dismiss the boot animation if the keyguard has finished drawing,
+ // or mBootAnimationDismissable has been set
+ return mDefaultDisplayPolicy.isKeyguardDrawComplete() || mBootAnimationDismissable;
}
ProgressDialog mBootMsgDialog = null;
@@ -5205,6 +5275,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
pw.print("mTriplePressOnPowerBehavior=");
pw.println(multiPressOnPowerBehaviorToString(mTriplePressOnPowerBehavior));
pw.print(prefix);
+ pw.print("mPowerVolUpBehavior=");
+ pw.println(powerVolumeUpBehaviorToString(mPowerVolUpBehavior));
+ pw.print(prefix);
pw.print("mShortPressOnSleepBehavior=");
pw.println(shortPressOnSleepBehaviorToString(mShortPressOnSleepBehavior));
pw.print(prefix);
@@ -5378,6 +5451,19 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
+ private static String powerVolumeUpBehaviorToString(int behavior) {
+ switch (behavior) {
+ case POWER_VOLUME_UP_BEHAVIOR_NOTHING:
+ return "POWER_VOLUME_UP_BEHAVIOR_NOTHING";
+ case POWER_VOLUME_UP_BEHAVIOR_MUTE:
+ return "POWER_VOLUME_UP_BEHAVIOR_MUTE";
+ case POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS:
+ return "POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS";
+ default:
+ return Integer.toString(behavior);
+ }
+ }
+
private static String multiPressOnPowerBehaviorToString(int behavior) {
switch (behavior) {
case MULTI_PRESS_POWER_NOTHING:
diff --git a/services/core/java/com/android/server/power/FaceDownDetector.java b/services/core/java/com/android/server/power/FaceDownDetector.java
index 676181dcfb67..474ce59212ff 100644
--- a/services/core/java/com/android/server/power/FaceDownDetector.java
+++ b/services/core/java/com/android/server/power/FaceDownDetector.java
@@ -35,6 +35,7 @@ import android.os.SystemClock;
import android.provider.DeviceConfig;
import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FrameworkStatsLog;
import java.io.PrintWriter;
@@ -59,6 +60,8 @@ public class FaceDownDetector implements SensorEventListener {
FrameworkStatsLog.FACE_DOWN_REPORTED__FACE_DOWN_RESPONSE__USER_INTERACTION;
private static final int UNFLIP =
FrameworkStatsLog.FACE_DOWN_REPORTED__FACE_DOWN_RESPONSE__UNFLIP;
+ private static final int UNKNOWN =
+ FrameworkStatsLog.FACE_DOWN_REPORTED__FACE_DOWN_RESPONSE__UNKNOWN;
/**
* Used by the ExponentialMovingAverage accelerations, this determines how quickly the
@@ -130,7 +133,7 @@ public class FaceDownDetector implements SensorEventListener {
/** Values we store for logging purposes. */
private long mLastFlipTime = 0L;
- public int mPreviousResultType = 0;
+ public int mPreviousResultType = UNKNOWN;
public long mPreviousResultTime = 0L;
private long mMillisSaved = 0L;
@@ -151,7 +154,8 @@ public class FaceDownDetector implements SensorEventListener {
private final Handler mHandler;
private final Runnable mUserActivityRunnable;
- private final BroadcastReceiver mScreenReceiver;
+ @VisibleForTesting
+ final BroadcastReceiver mScreenReceiver;
private Context mContext;
@@ -203,6 +207,10 @@ public class FaceDownDetector implements SensorEventListener {
logScreenOff();
}
} else {
+ if (mFaceDown && !mInteractive) {
+ mPreviousResultType = SCREEN_OFF_RESULT;
+ mPreviousResultTime = currentTime;
+ }
mSensorManager.unregisterListener(this);
mFaceDown = false;
mOnFlip.accept(false);
@@ -311,15 +319,13 @@ public class FaceDownDetector implements SensorEventListener {
}
private void logScreenOff() {
- if (mPreviousResultType == SCREEN_OFF_RESULT) {
- final long currentTime = SystemClock.uptimeMillis();
- FrameworkStatsLog.write(FrameworkStatsLog.FACE_DOWN_REPORTED,
- mPreviousResultType,
- /* millis_since_flip= */ mPreviousResultTime - mLastFlipTime,
- mMillisSaved,
- /* millis_until_next_screen_on= */ currentTime - mPreviousResultTime);
- mPreviousResultType = -1;
- }
+ final long currentTime = SystemClock.uptimeMillis();
+ FrameworkStatsLog.write(FrameworkStatsLog.FACE_DOWN_REPORTED,
+ SCREEN_OFF_RESULT,
+ /* millis_since_flip= */ mPreviousResultTime - mLastFlipTime,
+ mMillisSaved,
+ /* millis_until_next_screen_on= */ currentTime - mPreviousResultTime);
+ mPreviousResultType = UNKNOWN;
}
private boolean isEnabled() {
diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
new file mode 100644
index 000000000000..fc7628c28b8b
--- /dev/null
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -0,0 +1,449 @@
+/*
+ * 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.power.hint;
+
+import android.app.ActivityManager;
+import android.app.IUidObserver;
+import android.content.Context;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.IHintManager;
+import android.os.IHintSession;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.DumpUtils;
+import com.android.internal.util.Preconditions;
+import com.android.server.FgThread;
+import com.android.server.SystemService;
+import com.android.server.utils.Slogf;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Arrays;
+
+/** An hint service implementation that runs in System Server process. */
+public final class HintManagerService extends SystemService {
+ private static final String TAG = "HintManagerService";
+ private static final boolean DEBUG = false;
+ @VisibleForTesting final long mHintSessionPreferredRate;
+
+ @GuardedBy("mLock")
+ private final ArrayMap<Integer, ArrayMap<IBinder, AppHintSession>> mActiveSessions;
+
+ /** Lock to protect HAL handles and listen list. */
+ private final Object mLock = new Object();
+
+ @VisibleForTesting final UidObserver mUidObserver;
+
+ private final NativeWrapper mNativeWrapper;
+
+ @VisibleForTesting final IHintManager.Stub mService = new BinderService();
+
+ public HintManagerService(Context context) {
+ this(context, new Injector());
+ }
+
+ @VisibleForTesting
+ HintManagerService(Context context, Injector injector) {
+ super(context);
+ mActiveSessions = new ArrayMap<>();
+ mNativeWrapper = injector.createNativeWrapper();
+ mNativeWrapper.halInit();
+ mHintSessionPreferredRate = mNativeWrapper.halGetHintSessionPreferredRate();
+ mUidObserver = new UidObserver();
+ }
+
+ @VisibleForTesting
+ static class Injector {
+ NativeWrapper createNativeWrapper() {
+ return new NativeWrapper();
+ }
+ }
+
+ private boolean isHalSupported() {
+ return mHintSessionPreferredRate != -1;
+ }
+
+ @Override
+ public void onStart() {
+ publishBinderService(Context.PERFORMANCE_HINT_SERVICE, mService, /* allowIsolated= */ true);
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
+ systemReady();
+ }
+ }
+
+ private void systemReady() {
+ Slogf.v(TAG, "Initializing HintManager service...");
+ try {
+ ActivityManager.getService().registerUidObserver(mUidObserver,
+ ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE,
+ ActivityManager.PROCESS_STATE_UNKNOWN, null);
+ } catch (RemoteException e) {
+ // ignored; both services live in system_server
+ }
+
+ }
+
+ /**
+ * Wrapper around the static-native methods from native.
+ *
+ * This class exists to allow us to mock static native methods in our tests. If mocking static
+ * methods becomes easier than this in the future, we can delete this class.
+ */
+ @VisibleForTesting
+ public static class NativeWrapper {
+ private native void nativeInit();
+
+ private static native long nativeCreateHintSession(int tgid, int uid, int[] tids,
+ long durationNanos);
+
+ private static native void nativePauseHintSession(long halPtr);
+
+ private static native void nativeResumeHintSession(long halPtr);
+
+ private static native void nativeCloseHintSession(long halPtr);
+
+ private static native void nativeUpdateTargetWorkDuration(
+ long halPtr, long targetDurationNanos);
+
+ private static native void nativeReportActualWorkDuration(
+ long halPtr, long[] actualDurationNanos, long[] timeStampNanos);
+
+ private static native long nativeGetHintSessionPreferredRate();
+
+ /** Wrapper for HintManager.nativeInit */
+ public void halInit() {
+ nativeInit();
+ }
+
+ /** Wrapper for HintManager.nativeCreateHintSession */
+ public long halCreateHintSession(int tgid, int uid, int[] tids, long durationNanos) {
+ return nativeCreateHintSession(tgid, uid, tids, durationNanos);
+ }
+
+ /** Wrapper for HintManager.nativePauseHintSession */
+ public void halPauseHintSession(long halPtr) {
+ nativePauseHintSession(halPtr);
+ }
+
+ /** Wrapper for HintManager.nativeResumeHintSession */
+ public void halResumeHintSession(long halPtr) {
+ nativeResumeHintSession(halPtr);
+ }
+
+ /** Wrapper for HintManager.nativeCloseHintSession */
+ public void halCloseHintSession(long halPtr) {
+ nativeCloseHintSession(halPtr);
+ }
+
+ /** Wrapper for HintManager.nativeUpdateTargetWorkDuration */
+ public void halUpdateTargetWorkDuration(long halPtr, long targetDurationNanos) {
+ nativeUpdateTargetWorkDuration(halPtr, targetDurationNanos);
+ }
+
+ /** Wrapper for HintManager.nativeReportActualWorkDuration */
+ public void halReportActualWorkDuration(
+ long halPtr, long[] actualDurationNanos, long[] timeStampNanos) {
+ nativeReportActualWorkDuration(halPtr, actualDurationNanos,
+ timeStampNanos);
+ }
+
+ /** Wrapper for HintManager.nativeGetHintSessionPreferredRate */
+ public long halGetHintSessionPreferredRate() {
+ return nativeGetHintSessionPreferredRate();
+ }
+ }
+
+ @VisibleForTesting
+ final class UidObserver extends IUidObserver.Stub {
+ private final SparseArray<Integer> mProcStatesCache = new SparseArray<>();
+
+ public boolean isUidForeground(int uid) {
+ synchronized (mLock) {
+ return mProcStatesCache.get(uid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)
+ <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+ }
+ }
+
+ @Override
+ public void onUidGone(int uid, boolean disabled) {
+ FgThread.getHandler().post(() -> {
+ synchronized (mLock) {
+ ArrayMap<IBinder, AppHintSession> tokenMap = mActiveSessions.get(uid);
+ if (tokenMap == null) {
+ return;
+ }
+ for (int i = tokenMap.size() - 1; i >= 0; i--) {
+ // Will remove the session from tokenMap
+ tokenMap.valueAt(i).close();
+ }
+ mProcStatesCache.delete(uid);
+ }
+ });
+ }
+
+ @Override
+ public void onUidActive(int uid) {
+ }
+
+ @Override
+ public void onUidIdle(int uid, boolean disabled) {
+ }
+
+ /**
+ * The IUidObserver callback is called from the system_server, so it'll be a direct function
+ * call from ActivityManagerService. Do not do heavy logic here.
+ */
+ @Override
+ public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
+ FgThread.getHandler().post(() -> {
+ synchronized (mLock) {
+ mProcStatesCache.put(uid, procState);
+ ArrayMap<IBinder, AppHintSession> tokenMap = mActiveSessions.get(uid);
+ if (tokenMap == null) {
+ return;
+ }
+ for (AppHintSession s : tokenMap.values()) {
+ s.onProcStateChanged();
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onUidCachedChanged(int uid, boolean cached) {
+ }
+ }
+
+ @VisibleForTesting
+ IHintManager.Stub getBinderServiceInstance() {
+ return mService;
+ }
+
+ private boolean checkTidValid(int tgid, int [] tids) {
+ // Make sure all tids belongs to the same process.
+ for (int threadId : tids) {
+ if (!Process.isThreadInProcess(tgid, threadId)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @VisibleForTesting
+ final class BinderService extends IHintManager.Stub {
+ @Override
+ public IHintSession createHintSession(IBinder token, int[] tids, long durationNanos) {
+ if (!isHalSupported()) return null;
+
+ java.util.Objects.requireNonNull(token);
+ java.util.Objects.requireNonNull(tids);
+ Preconditions.checkArgument(tids.length != 0, "tids should"
+ + " not be empty.");
+
+ int uid = Binder.getCallingUid();
+ int tid = Binder.getCallingPid();
+ int pid = Process.getThreadGroupLeader(tid);
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ if (!checkTidValid(pid, tids)) {
+ throw new SecurityException("Some tid doesn't belong to the process");
+ }
+
+ long halSessionPtr = mNativeWrapper.halCreateHintSession(pid, uid, tids,
+ durationNanos);
+ if (halSessionPtr == 0) return null;
+
+ AppHintSession hs = new AppHintSession(uid, pid, tids, token,
+ halSessionPtr, durationNanos);
+ synchronized (mLock) {
+ ArrayMap<IBinder, AppHintSession> tokenMap = mActiveSessions.get(uid);
+ if (tokenMap == null) {
+ tokenMap = new ArrayMap<>(1);
+ mActiveSessions.put(uid, tokenMap);
+ }
+ tokenMap.put(token, hs);
+ return hs;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public long getHintSessionPreferredRate() {
+ return mHintSessionPreferredRate;
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) {
+ return;
+ }
+ synchronized (mLock) {
+ pw.println("HintSessionPreferredRate: " + mHintSessionPreferredRate);
+ pw.println("HAL Support: " + isHalSupported());
+ pw.println("Active Sessions:");
+ for (int i = 0; i < mActiveSessions.size(); i++) {
+ pw.println("Uid " + mActiveSessions.keyAt(i).toString() + ":");
+ ArrayMap<IBinder, AppHintSession> tokenMap = mActiveSessions.valueAt(i);
+ for (int j = 0; j < tokenMap.size(); j++) {
+ pw.println(" Session " + j + ":");
+ tokenMap.valueAt(j).dump(pw, " ");
+ }
+ }
+ }
+ }
+ }
+
+ @VisibleForTesting
+ final class AppHintSession extends IHintSession.Stub implements IBinder.DeathRecipient {
+ protected final int mUid;
+ protected final int mPid;
+ protected final int[] mThreadIds;
+ protected final IBinder mToken;
+ protected long mHalSessionPtr;
+ protected long mTargetDurationNanos;
+ protected boolean mUpdateAllowed;
+
+ protected AppHintSession(
+ int uid, int pid, int[] threadIds, IBinder token,
+ long halSessionPtr, long durationNanos) {
+ mUid = uid;
+ mPid = pid;
+ mToken = token;
+ mThreadIds = threadIds;
+ mHalSessionPtr = halSessionPtr;
+ mTargetDurationNanos = durationNanos;
+ mUpdateAllowed = true;
+ updateHintAllowed();
+ try {
+ token.linkToDeath(this, 0);
+ } catch (RemoteException e) {
+ mNativeWrapper.halCloseHintSession(mHalSessionPtr);
+ throw new IllegalStateException("Client already dead", e);
+ }
+ }
+
+ @VisibleForTesting
+ boolean updateHintAllowed() {
+ synchronized (mLock) {
+ final boolean allowed = mUidObserver.isUidForeground(mUid);
+ if (allowed && !mUpdateAllowed) resume();
+ if (!allowed && mUpdateAllowed) pause();
+ mUpdateAllowed = allowed;
+ return mUpdateAllowed;
+ }
+ }
+
+ @Override
+ public void updateTargetWorkDuration(long targetDurationNanos) {
+ synchronized (mLock) {
+ if (mHalSessionPtr == 0 || !updateHintAllowed()) {
+ return;
+ }
+ Preconditions.checkArgument(targetDurationNanos > 0, "Expected"
+ + " the target duration to be greater than 0.");
+ mNativeWrapper.halUpdateTargetWorkDuration(mHalSessionPtr, targetDurationNanos);
+ mTargetDurationNanos = targetDurationNanos;
+ }
+ }
+
+ @Override
+ public void reportActualWorkDuration(long[] actualDurationNanos, long[] timeStampNanos) {
+ synchronized (mLock) {
+ if (mHalSessionPtr == 0 || !updateHintAllowed()) {
+ return;
+ }
+ Preconditions.checkArgument(actualDurationNanos.length != 0, "the count"
+ + " of hint durations shouldn't be 0.");
+ Preconditions.checkArgument(actualDurationNanos.length == timeStampNanos.length,
+ "The length of durations and timestamps should be the same.");
+ for (int i = 0; i < actualDurationNanos.length; i++) {
+ if (actualDurationNanos[i] <= 0) {
+ throw new IllegalArgumentException(
+ String.format("durations[%d]=%d should be greater than 0",
+ i, actualDurationNanos[i]));
+ }
+ }
+ mNativeWrapper.halReportActualWorkDuration(mHalSessionPtr, actualDurationNanos,
+ timeStampNanos);
+ }
+ }
+
+ /** TODO: consider monitor session threads and close session if any thread is dead. */
+ @Override
+ public void close() {
+ synchronized (mLock) {
+ if (mHalSessionPtr == 0) return;
+ mNativeWrapper.halCloseHintSession(mHalSessionPtr);
+ mHalSessionPtr = 0;
+ mToken.unlinkToDeath(this, 0);
+ ArrayMap<IBinder, AppHintSession> tokenMap = mActiveSessions.get(mUid);
+ if (tokenMap == null) {
+ Slogf.w(TAG, "UID %d is note present in active session map", mUid);
+ }
+ tokenMap.remove(mToken);
+ if (tokenMap.isEmpty()) mActiveSessions.remove(mUid);
+ }
+ }
+
+ private void onProcStateChanged() {
+ updateHintAllowed();
+ }
+
+ private void pause() {
+ synchronized (mLock) {
+ if (mHalSessionPtr == 0) return;
+ mNativeWrapper.halPauseHintSession(mHalSessionPtr);
+ }
+ }
+
+ private void resume() {
+ synchronized (mLock) {
+ if (mHalSessionPtr == 0) return;
+ mNativeWrapper.halResumeHintSession(mHalSessionPtr);
+ }
+ }
+
+ private void dump(PrintWriter pw, String prefix) {
+ synchronized (mLock) {
+ pw.println(prefix + "SessionPID: " + mPid);
+ pw.println(prefix + "SessionUID: " + mUid);
+ pw.println(prefix + "SessionTIDs: " + Arrays.toString(mThreadIds));
+ pw.println(prefix + "SessionTargetDurationNanos: " + mTargetDurationNanos);
+ pw.println(prefix + "SessionAllowed: " + updateHintAllowed());
+ }
+ }
+
+ @Override
+ public void binderDied() {
+ close();
+ }
+
+ }
+}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 970420a284d6..a436e6b3787b 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -18,6 +18,7 @@ package com.android.server.statusbar;
import android.annotation.Nullable;
import android.app.ITransientNotificationCallback;
+import android.hardware.fingerprint.IUdfpsHbmListener;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
@@ -166,4 +167,11 @@ public interface StatusBarManagerInternal {
* boolean)
*/
void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable);
+
+ /**
+ * Sets the system-wide listener for UDFPS HBM status changes.
+ *
+ * @see com.android.internal.statusbar.IStatusBar#setUdfpsHbmListener(IUdfpsHbmListener)
+ */
+ void setUdfpsHbmListener(IUdfpsHbmListener listener);
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index c4f5575c22ab..e37edebb09ba 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -107,15 +107,15 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
private final Context mContext;
- private Handler mHandler = new Handler();
+ private final Handler mHandler = new Handler();
private NotificationDelegate mNotificationDelegate;
private volatile IStatusBar mBar;
- private ArrayMap<String, StatusBarIcon> mIcons = new ArrayMap<>();
+ private final ArrayMap<String, StatusBarIcon> mIcons = new ArrayMap<>();
// for disabling the status bar
private final ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
private GlobalActionsProvider.GlobalActionsListener mGlobalActionListener;
- private IBinder mSysUiVisToken = new Binder();
+ private final IBinder mSysUiVisToken = new Binder();
private final Object mLock = new Object();
private final DeathRecipient mDeathRecipient = new DeathRecipient();
@@ -123,7 +123,9 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
private int mCurrentUserId;
private boolean mTracingEnabled;
- private SparseArray<UiState> mDisplayUiState = new SparseArray<>();
+ private final SparseArray<UiState> mDisplayUiState = new SparseArray<>();
+ @GuardedBy("mLock")
+ private IUdfpsHbmListener mUdfpsHbmListener;
private class DeathRecipient implements IBinder.DeathRecipient {
public void binderDied() {
@@ -598,6 +600,18 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
} catch (RemoteException ex) { }
}
}
+
+ @Override
+ public void setUdfpsHbmListener(IUdfpsHbmListener listener) {
+ synchronized (mLock) {
+ mUdfpsHbmListener = listener;
+ }
+ if (mBar != null) {
+ try {
+ mBar.setUdfpsHbmListener(listener);
+ } catch (RemoteException ex) { }
+ }
+ }
};
private final GlobalActionsProvider mGlobalActionsProvider = new GlobalActionsProvider() {
@@ -1204,6 +1218,14 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
if (mGlobalActionListener == null) return;
mGlobalActionListener.onGlobalActionsAvailableChanged(mBar != null);
});
+ // If StatusBarService dies, system_server doesn't get killed with it, so we need to make
+ // sure the UDFPS listener is refreshed as well. Deferring to the handler just so to avoid
+ // making registerStatusBar re-entrant.
+ mHandler.post(() -> {
+ synchronized (mLock) {
+ setUdfpsHbmListener(mUdfpsHbmListener);
+ }
+ });
}
/**
diff --git a/services/core/java/com/android/server/utils/ManagedApplicationService.java b/services/core/java/com/android/server/utils/ManagedApplicationService.java
index c103e0e60696..4cf0e3229bd8 100644
--- a/services/core/java/com/android/server/utils/ManagedApplicationService.java
+++ b/services/core/java/com/android/server/utils/ManagedApplicationService.java
@@ -304,7 +304,8 @@ public class ManagedApplicationService {
}
if (mSettingsAction != null) {
intent.putExtra(Intent.EXTRA_CLIENT_INTENT,
- PendingIntent.getActivity(mContext, 0, new Intent(mSettingsAction), PendingIntent.FLAG_MUTABLE_UNAUDITED));
+ PendingIntent.getActivity(mContext, 0, new Intent(mSettingsAction),
+ PendingIntent.FLAG_IMMUTABLE));
}
mConnection = new ServiceConnection() {
diff --git a/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java b/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java
index 96f84dc65e1d..21ba87445478 100644
--- a/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java
+++ b/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java
@@ -19,7 +19,7 @@ package com.android.server.vibrator;
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.input.InputManager;
-import android.os.CombinedVibrationEffect;
+import android.os.CombinedVibration;
import android.os.Handler;
import android.os.VibrationAttributes;
import android.os.VibratorManager;
@@ -94,7 +94,7 @@ final class InputDeviceDelegate implements InputManager.InputDeviceListener {
*
* @return {@link #isAvailable()}
*/
- public boolean vibrateIfAvailable(int uid, String opPkg, CombinedVibrationEffect effect,
+ public boolean vibrateIfAvailable(int uid, String opPkg, CombinedVibration effect,
String reason, VibrationAttributes attrs) {
synchronized (mLock) {
for (int i = 0; i < mInputDeviceVibrators.size(); i++) {
diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java
index cd840589475a..e447a23cf331 100644
--- a/services/core/java/com/android/server/vibrator/Vibration.java
+++ b/services/core/java/com/android/server/vibrator/Vibration.java
@@ -17,7 +17,7 @@
package com.android.server.vibrator;
import android.annotation.Nullable;
-import android.os.CombinedVibrationEffect;
+import android.os.CombinedVibration;
import android.os.IBinder;
import android.os.SystemClock;
import android.os.VibrationAttributes;
@@ -72,14 +72,14 @@ final class Vibration {
/** The actual effect to be played. */
@Nullable
- private CombinedVibrationEffect mEffect;
+ private CombinedVibration mEffect;
/**
* The original effect that was requested. Typically these two things differ because the effect
* was scaled based on the users vibration intensity settings.
*/
@Nullable
- private CombinedVibrationEffect mOriginalEffect;
+ private CombinedVibration mOriginalEffect;
/**
* Start/end times in unix epoch time. Only to be used for debugging purposes and to correlate
@@ -90,7 +90,7 @@ final class Vibration {
private long mEndTimeDebug;
private Status mStatus;
- Vibration(IBinder token, int id, CombinedVibrationEffect effect,
+ Vibration(IBinder token, int id, CombinedVibration effect,
VibrationAttributes attrs, int uid, String opPkg, String reason) {
this.token = token;
this.mEffect = effect;
@@ -142,7 +142,7 @@ final class Vibration {
* effect added.
*/
public void updateEffects(Function<VibrationEffect, VibrationEffect> updateFn) {
- CombinedVibrationEffect newEffect = transformCombinedEffect(mEffect, updateFn);
+ CombinedVibration newEffect = transformCombinedEffect(mEffect, updateFn);
if (!newEffect.equals(mEffect)) {
if (mOriginalEffect == null) {
mOriginalEffect = mEffect;
@@ -155,29 +155,29 @@ final class Vibration {
}
/**
- * Creates a new {@link CombinedVibrationEffect} by applying the given transformation function
+ * Creates a new {@link CombinedVibration} by applying the given transformation function
* to each {@link VibrationEffect}.
*/
- private static CombinedVibrationEffect transformCombinedEffect(
- CombinedVibrationEffect combinedEffect, Function<VibrationEffect, VibrationEffect> fn) {
- if (combinedEffect instanceof CombinedVibrationEffect.Mono) {
- VibrationEffect effect = ((CombinedVibrationEffect.Mono) combinedEffect).getEffect();
- return CombinedVibrationEffect.createSynced(fn.apply(effect));
- } else if (combinedEffect instanceof CombinedVibrationEffect.Stereo) {
+ private static CombinedVibration transformCombinedEffect(
+ CombinedVibration combinedEffect, Function<VibrationEffect, VibrationEffect> fn) {
+ if (combinedEffect instanceof CombinedVibration.Mono) {
+ VibrationEffect effect = ((CombinedVibration.Mono) combinedEffect).getEffect();
+ return CombinedVibration.createParallel(fn.apply(effect));
+ } else if (combinedEffect instanceof CombinedVibration.Stereo) {
SparseArray<VibrationEffect> effects =
- ((CombinedVibrationEffect.Stereo) combinedEffect).getEffects();
- CombinedVibrationEffect.SyncedCombination combination =
- CombinedVibrationEffect.startSynced();
+ ((CombinedVibration.Stereo) combinedEffect).getEffects();
+ CombinedVibration.ParallelCombination combination =
+ CombinedVibration.startParallel();
for (int i = 0; i < effects.size(); i++) {
combination.addVibrator(effects.keyAt(i), fn.apply(effects.valueAt(i)));
}
return combination.combine();
- } else if (combinedEffect instanceof CombinedVibrationEffect.Sequential) {
- List<CombinedVibrationEffect> effects =
- ((CombinedVibrationEffect.Sequential) combinedEffect).getEffects();
- CombinedVibrationEffect.SequentialCombination combination =
- CombinedVibrationEffect.startSequential();
- for (CombinedVibrationEffect effect : effects) {
+ } else if (combinedEffect instanceof CombinedVibration.Sequential) {
+ List<CombinedVibration> effects =
+ ((CombinedVibration.Sequential) combinedEffect).getEffects();
+ CombinedVibration.SequentialCombination combination =
+ CombinedVibration.startSequential();
+ for (CombinedVibration effect : effects) {
combination.addNext(transformCombinedEffect(effect, fn));
}
return combination.combine();
@@ -199,7 +199,7 @@ final class Vibration {
/** Return the effect that should be played by this vibration. */
@Nullable
- public CombinedVibrationEffect getEffect() {
+ public CombinedVibration getEffect() {
return mEffect;
}
@@ -214,8 +214,8 @@ final class Vibration {
static final class DebugInfo {
private final long mStartTimeDebug;
private final long mEndTimeDebug;
- private final CombinedVibrationEffect mEffect;
- private final CombinedVibrationEffect mOriginalEffect;
+ private final CombinedVibration mEffect;
+ private final CombinedVibration mOriginalEffect;
private final float mScale;
private final VibrationAttributes mAttrs;
private final int mUid;
@@ -223,8 +223,8 @@ final class Vibration {
private final String mReason;
private final Status mStatus;
- DebugInfo(long startTimeDebug, long endTimeDebug, CombinedVibrationEffect effect,
- CombinedVibrationEffect originalEffect, float scale, VibrationAttributes attrs,
+ DebugInfo(long startTimeDebug, long endTimeDebug, CombinedVibration effect,
+ CombinedVibration originalEffect, float scale, VibrationAttributes attrs,
int uid, String opPkg, String reason, Status status) {
mStartTimeDebug = startTimeDebug;
mEndTimeDebug = endTimeDebug;
@@ -289,24 +289,24 @@ final class Vibration {
}
private void dumpEffect(
- ProtoOutputStream proto, long fieldId, CombinedVibrationEffect effect) {
+ ProtoOutputStream proto, long fieldId, CombinedVibration effect) {
dumpEffect(proto, fieldId,
- (CombinedVibrationEffect.Sequential) CombinedVibrationEffect.startSequential()
+ (CombinedVibration.Sequential) CombinedVibration.startSequential()
.addNext(effect)
.combine());
}
private void dumpEffect(
- ProtoOutputStream proto, long fieldId, CombinedVibrationEffect.Sequential effect) {
+ ProtoOutputStream proto, long fieldId, CombinedVibration.Sequential effect) {
final long token = proto.start(fieldId);
for (int i = 0; i < effect.getEffects().size(); i++) {
- CombinedVibrationEffect nestedEffect = effect.getEffects().get(i);
- if (nestedEffect instanceof CombinedVibrationEffect.Mono) {
+ CombinedVibration nestedEffect = effect.getEffects().get(i);
+ if (nestedEffect instanceof CombinedVibration.Mono) {
dumpEffect(proto, CombinedVibrationEffectProto.EFFECTS,
- (CombinedVibrationEffect.Mono) nestedEffect);
- } else if (nestedEffect instanceof CombinedVibrationEffect.Stereo) {
+ (CombinedVibration.Mono) nestedEffect);
+ } else if (nestedEffect instanceof CombinedVibration.Stereo) {
dumpEffect(proto, CombinedVibrationEffectProto.EFFECTS,
- (CombinedVibrationEffect.Stereo) nestedEffect);
+ (CombinedVibration.Stereo) nestedEffect);
}
proto.write(CombinedVibrationEffectProto.DELAYS, effect.getDelays().get(i));
}
@@ -314,14 +314,14 @@ final class Vibration {
}
private void dumpEffect(
- ProtoOutputStream proto, long fieldId, CombinedVibrationEffect.Mono effect) {
+ ProtoOutputStream proto, long fieldId, CombinedVibration.Mono effect) {
final long token = proto.start(fieldId);
dumpEffect(proto, SyncVibrationEffectProto.EFFECTS, effect.getEffect());
proto.end(token);
}
private void dumpEffect(
- ProtoOutputStream proto, long fieldId, CombinedVibrationEffect.Stereo effect) {
+ ProtoOutputStream proto, long fieldId, CombinedVibration.Stereo effect) {
final long token = proto.start(fieldId);
for (int i = 0; i < effect.getEffects().size(); i++) {
proto.write(SyncVibrationEffectProto.VIBRATOR_IDS, effect.getEffects().keyAt(i));
diff --git a/services/core/java/com/android/server/vibrator/VibrationThread.java b/services/core/java/com/android/server/vibrator/VibrationThread.java
index df85e262bd5d..bc61478ec1b5 100644
--- a/services/core/java/com/android/server/vibrator/VibrationThread.java
+++ b/services/core/java/com/android/server/vibrator/VibrationThread.java
@@ -19,7 +19,7 @@ package com.android.server.vibrator;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.hardware.vibrator.IVibratorManager;
-import android.os.CombinedVibrationEffect;
+import android.os.CombinedVibration;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.Process;
@@ -112,7 +112,7 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
mWakeLock.setWorkSource(mWorkSource);
mBatteryStatsService = batteryStatsService;
- CombinedVibrationEffect effect = vib.getEffect();
+ CombinedVibration effect = vib.getEffect();
for (int i = 0; i < availableVibrators.size(); i++) {
if (effect.hasVibrator(availableVibrators.keyAt(i))) {
mVibrators.put(availableVibrators.keyAt(i), availableVibrators.valueAt(i));
@@ -191,7 +191,7 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
private Vibration.Status playVibration() {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "playVibration");
try {
- CombinedVibrationEffect.Sequential effect = toSequential(mVibration.getEffect());
+ CombinedVibration.Sequential effect = toSequential(mVibration.getEffect());
int stepsPlayed = 0;
synchronized (mLock) {
@@ -255,9 +255,6 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
@Nullable
private SingleVibratorStep nextVibrateStep(long startTime, VibratorController controller,
VibrationEffect.Composed effect, int segmentIndex, long vibratorOffTimeout) {
- // Some steps should only start after the vibrator has finished the previous vibration, so
- // make sure we take the latest between both timings.
- long latestStartTime = Math.max(startTime, vibratorOffTimeout);
if (segmentIndex >= effect.getSegments().size()) {
segmentIndex = effect.getRepeatIndex();
}
@@ -272,25 +269,24 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
VibrationEffectSegment segment = effect.getSegments().get(segmentIndex);
if (segment instanceof PrebakedSegment) {
- return new PerformStep(latestStartTime, controller, effect, segmentIndex,
- vibratorOffTimeout);
+ return new PerformStep(startTime, controller, effect, segmentIndex, vibratorOffTimeout);
}
if (segment instanceof PrimitiveSegment) {
- return new ComposePrimitivesStep(latestStartTime, controller, effect, segmentIndex,
+ return new ComposePrimitivesStep(startTime, controller, effect, segmentIndex,
vibratorOffTimeout);
}
if (segment instanceof RampSegment) {
- return new ComposePwleStep(latestStartTime, controller, effect, segmentIndex,
+ return new ComposePwleStep(startTime, controller, effect, segmentIndex,
vibratorOffTimeout);
}
return new AmplitudeStep(startTime, controller, effect, segmentIndex, vibratorOffTimeout);
}
- private static CombinedVibrationEffect.Sequential toSequential(CombinedVibrationEffect effect) {
- if (effect instanceof CombinedVibrationEffect.Sequential) {
- return (CombinedVibrationEffect.Sequential) effect;
+ private static CombinedVibration.Sequential toSequential(CombinedVibration effect) {
+ if (effect instanceof CombinedVibration.Sequential) {
+ return (CombinedVibration.Sequential) effect;
}
- return (CombinedVibrationEffect.Sequential) CombinedVibrationEffect.startSequential()
+ return (CombinedVibration.Sequential) CombinedVibration.startSequential()
.addNext(effect)
.combine();
}
@@ -419,14 +415,14 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
* sequential effect isn't finished yet.
*/
private final class StartVibrateStep extends Step {
- public final CombinedVibrationEffect.Sequential sequentialEffect;
+ public final CombinedVibration.Sequential sequentialEffect;
public final int currentIndex;
- StartVibrateStep(CombinedVibrationEffect.Sequential effect) {
+ StartVibrateStep(CombinedVibration.Sequential effect) {
this(SystemClock.uptimeMillis() + effect.getDelays().get(0), effect, /* index= */ 0);
}
- StartVibrateStep(long startTime, CombinedVibrationEffect.Sequential effect, int index) {
+ StartVibrateStep(long startTime, CombinedVibration.Sequential effect, int index) {
super(startTime);
sequentialEffect = effect;
currentIndex = index;
@@ -441,7 +437,7 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
if (DEBUG) {
Slog.d(TAG, "StartVibrateStep for effect #" + currentIndex);
}
- CombinedVibrationEffect effect = sequentialEffect.getEffects().get(currentIndex);
+ CombinedVibration effect = sequentialEffect.getEffects().get(currentIndex);
DeviceEffectMap effectMapping = createEffectToVibratorMapping(effect);
if (effectMapping == null) {
// Unable to map effects to vibrators, ignore this step.
@@ -485,12 +481,12 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
/** Create a mapping of individual {@link VibrationEffect} to available vibrators. */
@Nullable
private DeviceEffectMap createEffectToVibratorMapping(
- CombinedVibrationEffect effect) {
- if (effect instanceof CombinedVibrationEffect.Mono) {
- return new DeviceEffectMap((CombinedVibrationEffect.Mono) effect);
+ CombinedVibration effect) {
+ if (effect instanceof CombinedVibration.Mono) {
+ return new DeviceEffectMap((CombinedVibration.Mono) effect);
}
- if (effect instanceof CombinedVibrationEffect.Stereo) {
- return new DeviceEffectMap((CombinedVibrationEffect.Stereo) effect);
+ if (effect instanceof CombinedVibration.Stereo) {
+ return new DeviceEffectMap((CombinedVibration.Stereo) effect);
}
return null;
}
@@ -498,11 +494,11 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
/**
* Starts playing effects on designated vibrators, in sync.
*
- * @param effectMapping The {@link CombinedVibrationEffect} mapped to this device vibrators
+ * @param effectMapping The {@link CombinedVibration} mapped to this device vibrators
* @param nextSteps An output list to accumulate the future {@link Step Steps} created
* by this method, typically one for each vibrator that has
* successfully started vibrating on this step.
- * @return The duration, in millis, of the {@link CombinedVibrationEffect}. Repeating
+ * @return The duration, in millis, of the {@link CombinedVibration}. Repeating
* waveforms return {@link Long#MAX_VALUE}. Zero or negative values indicate the vibrators
* have ignored all effects.
*/
@@ -572,7 +568,7 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
private long startVibrating(SingleVibratorStep step, List<Step> nextSteps) {
nextSteps.addAll(step.play());
- long stepDuration = step.getOnResult();
+ long stepDuration = step.getVibratorOnDuration();
if (stepDuration < 0) {
// Step failed, so return negative duration to propagate failure.
return stepDuration;
@@ -649,14 +645,13 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
}
/**
- * Return the result a call to {@link VibratorController#on} method triggered by
- * {@link #play()}.
+ * Return the duration the vibrator was turned on when this step was played.
*
* @return A positive duration that the vibrator was turned on for by this step;
- * Zero if the segment is not supported or vibrator was never turned on;
- * A negative value if the vibrator call has failed.
+ * Zero if the segment is not supported, the step was not played yet or vibrator was never
+ * turned on by this step; A negative value if the vibrator call has failed.
*/
- public long getOnResult() {
+ public long getVibratorOnDuration() {
return mVibratorOnResult;
}
@@ -690,7 +685,7 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
/**
* Return the {@link #nextVibrateStep} with same start and off timings calculated from
- * {@link #getOnResult()}, jumping all played segments.
+ * {@link #getVibratorOnDuration()}, jumping all played segments.
*
* <p>This method has same behavior as {@link #skipToNextSteps(int)} when the vibrator
* result is non-positive, meaning the vibrator has either ignored or failed to turn on.
@@ -730,7 +725,10 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
PerformStep(long startTime, VibratorController controller,
VibrationEffect.Composed effect, int index, long vibratorOffTimeout) {
- super(startTime, controller, effect, index, vibratorOffTimeout);
+ // This step should wait for the last vibration to finish (with the timeout) and for the
+ // intended step start time (to respect the effect delays).
+ super(Math.max(startTime, vibratorOffTimeout), controller, effect, index,
+ vibratorOffTimeout);
}
@Override
@@ -765,7 +763,7 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
List<Step> fallbackResult = fallbackStep.play();
// Update the result with the fallback result so this step is seamlessly
// replaced by the fallback to any outer application of this.
- mVibratorOnResult = fallbackStep.getOnResult();
+ mVibratorOnResult = fallbackStep.getVibratorOnDuration();
return fallbackResult;
}
@@ -802,7 +800,10 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
ComposePrimitivesStep(long startTime, VibratorController controller,
VibrationEffect.Composed effect, int index, long vibratorOffTimeout) {
- super(startTime, controller, effect, index, vibratorOffTimeout);
+ // This step should wait for the last vibration to finish (with the timeout) and for the
+ // intended step start time (to respect the effect delays).
+ super(Math.max(startTime, vibratorOffTimeout), controller, effect, index,
+ vibratorOffTimeout);
}
@Override
@@ -851,7 +852,10 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
ComposePwleStep(long startTime, VibratorController controller,
VibrationEffect.Composed effect, int index, long vibratorOffTimeout) {
- super(startTime, controller, effect, index, vibratorOffTimeout);
+ // This step should wait for the last vibration to finish (with the timeout) and for the
+ // intended step start time (to respect the effect delays).
+ super(Math.max(startTime, vibratorOffTimeout), controller, effect, index,
+ vibratorOffTimeout);
}
@Override
@@ -924,6 +928,7 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
AmplitudeStep(long startTime, VibratorController controller,
VibrationEffect.Composed effect, int index, long vibratorOffTimeout) {
+ // This step has a fixed startTime coming from the timings of the waveform it's playing.
super(startTime, controller, effect, index, vibratorOffTimeout);
mNextOffTime = vibratorOffTimeout;
}
@@ -1036,7 +1041,7 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
}
/**
- * Map a {@link CombinedVibrationEffect} to the vibrators available on the device.
+ * Map a {@link CombinedVibration} to the vibrators available on the device.
*
* <p>This contains the logic to find the capabilities required from {@link IVibratorManager} to
* play all of the effects in sync.
@@ -1046,7 +1051,7 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
private final int[] mVibratorIds;
private final long mRequiredSyncCapabilities;
- DeviceEffectMap(CombinedVibrationEffect.Mono mono) {
+ DeviceEffectMap(CombinedVibration.Mono mono) {
mVibratorEffects = new SparseArray<>(mVibrators.size());
mVibratorIds = new int[mVibrators.size()];
for (int i = 0; i < mVibrators.size(); i++) {
@@ -1061,7 +1066,7 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
mRequiredSyncCapabilities = calculateRequiredSyncCapabilities(mVibratorEffects);
}
- DeviceEffectMap(CombinedVibrationEffect.Stereo stereo) {
+ DeviceEffectMap(CombinedVibration.Stereo stereo) {
SparseArray<VibrationEffect> stereoEffects = stereo.getEffects();
mVibratorEffects = new SparseArray<>();
for (int i = 0; i < stereoEffects.size(); i++) {
@@ -1083,7 +1088,7 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
}
/**
- * Return the number of vibrators mapped to play the {@link CombinedVibrationEffect} on this
+ * Return the number of vibrators mapped to play the {@link CombinedVibration} on this
* device.
*/
public int size() {
@@ -1091,7 +1096,7 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
}
/**
- * Return all capabilities required to play the {@link CombinedVibrationEffect} in
+ * Return all capabilities required to play the {@link CombinedVibration} in
* between calls to {@link IVibratorManager#prepareSynced} and
* {@link IVibratorManager#triggerSynced}.
*/
@@ -1099,7 +1104,7 @@ final class VibrationThread extends Thread implements IBinder.DeathRecipient {
return mRequiredSyncCapabilities;
}
- /** Return all vibrator ids mapped to play the {@link CombinedVibrationEffect}. */
+ /** Return all vibrator ids mapped to play the {@link CombinedVibration}. */
public int[] getVibratorIds() {
return mVibratorIds;
}
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index b1d6050f82c2..5d2b1b169c4e 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -29,7 +29,7 @@ import android.content.pm.PackageManagerInternal;
import android.hardware.vibrator.IVibrator;
import android.os.BatteryStats;
import android.os.Binder;
-import android.os.CombinedVibrationEffect;
+import android.os.CombinedVibration;
import android.os.ExternalVibration;
import android.os.Handler;
import android.os.IBinder;
@@ -291,7 +291,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
@Override // Binder call
public boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId,
- @Nullable CombinedVibrationEffect effect, @Nullable VibrationAttributes attrs) {
+ @Nullable CombinedVibration effect, @Nullable VibrationAttributes attrs) {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "setAlwaysOnEffect");
try {
mContext.enforceCallingOrSelfPermission(
@@ -332,7 +332,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
}
@Override // Binder call
- public void vibrate(int uid, String opPkg, @NonNull CombinedVibrationEffect effect,
+ public void vibrate(int uid, String opPkg, @NonNull CombinedVibration effect,
@Nullable VibrationAttributes attrs, String reason, IBinder token) {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate, reason = " + reason);
try {
@@ -603,11 +603,20 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
// Repeating vibrations always take precedence.
return null;
}
- if (mCurrentVibration != null && mCurrentVibration.getVibration().isRepeating()) {
- if (DEBUG) {
- Slog.d(TAG, "Ignoring incoming vibration in favor of previous alarm vibration");
+ if (mCurrentVibration != null) {
+ if (mCurrentVibration.getVibration().attrs.getUsage()
+ == VibrationAttributes.USAGE_ALARM) {
+ if (DEBUG) {
+ Slog.d(TAG, "Ignoring incoming vibration in favor of alarm vibration");
+ }
+ return Vibration.Status.IGNORED_FOR_ALARM;
+ }
+ if (mCurrentVibration.getVibration().isRepeating()) {
+ if (DEBUG) {
+ Slog.d(TAG, "Ignoring incoming vibration in favor of repeating vibration");
+ }
+ return Vibration.Status.IGNORED_FOR_ONGOING;
}
- return Vibration.Status.IGNORED_FOR_ALARM;
}
return null;
}
@@ -733,14 +742,14 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
}
/**
- * Validate the incoming {@link CombinedVibrationEffect}.
+ * Validate the incoming {@link CombinedVibration}.
*
* We can't throw exceptions here since we might be called from some system_server component,
* which would bring the whole system down.
*
* @return whether the CombinedVibrationEffect is non-null and valid
*/
- private static boolean isEffectValid(@Nullable CombinedVibrationEffect effect) {
+ private static boolean isEffectValid(@Nullable CombinedVibration effect) {
if (effect == null) {
Slog.wtf(TAG, "effect must not be null");
return false;
@@ -758,18 +767,18 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
* Sets fallback effects to all prebaked ones in given combination of effects, based on {@link
* VibrationSettings#getFallbackEffect}.
*/
- private void fillVibrationFallbacks(Vibration vib, CombinedVibrationEffect effect) {
- if (effect instanceof CombinedVibrationEffect.Mono) {
- fillVibrationFallbacks(vib, ((CombinedVibrationEffect.Mono) effect).getEffect());
- } else if (effect instanceof CombinedVibrationEffect.Stereo) {
+ private void fillVibrationFallbacks(Vibration vib, CombinedVibration effect) {
+ if (effect instanceof CombinedVibration.Mono) {
+ fillVibrationFallbacks(vib, ((CombinedVibration.Mono) effect).getEffect());
+ } else if (effect instanceof CombinedVibration.Stereo) {
SparseArray<VibrationEffect> effects =
- ((CombinedVibrationEffect.Stereo) effect).getEffects();
+ ((CombinedVibration.Stereo) effect).getEffects();
for (int i = 0; i < effects.size(); i++) {
fillVibrationFallbacks(vib, effects.valueAt(i));
}
- } else if (effect instanceof CombinedVibrationEffect.Sequential) {
- List<CombinedVibrationEffect> effects =
- ((CombinedVibrationEffect.Sequential) effect).getEffects();
+ } else if (effect instanceof CombinedVibration.Sequential) {
+ List<CombinedVibration> effects =
+ ((CombinedVibration.Sequential) effect).getEffects();
for (int i = 0; i < effects.size(); i++) {
fillVibrationFallbacks(vib, effects.get(i));
}
@@ -816,15 +825,15 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
@GuardedBy("mLock")
@Nullable
private SparseArray<PrebakedSegment> fixupAlwaysOnEffectsLocked(
- CombinedVibrationEffect effect) {
+ CombinedVibration effect) {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "fixupAlwaysOnEffectsLocked");
try {
SparseArray<VibrationEffect> effects;
- if (effect instanceof CombinedVibrationEffect.Mono) {
- VibrationEffect syncedEffect = ((CombinedVibrationEffect.Mono) effect).getEffect();
+ if (effect instanceof CombinedVibration.Mono) {
+ VibrationEffect syncedEffect = ((CombinedVibration.Mono) effect).getEffect();
effects = transformAllVibratorsLocked(unused -> syncedEffect);
- } else if (effect instanceof CombinedVibrationEffect.Stereo) {
- effects = ((CombinedVibrationEffect.Stereo) effect).getEffects();
+ } else if (effect instanceof CombinedVibration.Stereo) {
+ effects = ((CombinedVibration.Stereo) effect).getEffects();
} else {
// Only synced combinations can be used for always-on effects.
return null;
@@ -1456,7 +1465,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
private int runMono() {
CommonOptions commonOptions = new CommonOptions();
- CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(nextEffect());
+ CombinedVibration effect = CombinedVibration.createParallel(nextEffect());
VibrationAttributes attrs = createVibrationAttributes(commonOptions);
vibrate(Binder.getCallingUid(), SHELL_PACKAGE_NAME, effect, attrs,
commonOptions.description, mToken);
@@ -1465,8 +1474,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
private int runStereo() {
CommonOptions commonOptions = new CommonOptions();
- CombinedVibrationEffect.SyncedCombination combination =
- CombinedVibrationEffect.startSynced();
+ CombinedVibration.ParallelCombination combination =
+ CombinedVibration.startParallel();
while ("-v".equals(getNextOption())) {
int vibratorId = Integer.parseInt(getNextArgRequired());
combination.addVibrator(vibratorId, nextEffect());
@@ -1479,8 +1488,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
private int runSequential() {
CommonOptions commonOptions = new CommonOptions();
- CombinedVibrationEffect.SequentialCombination combination =
- CombinedVibrationEffect.startSequential();
+ CombinedVibration.SequentialCombination combination =
+ CombinedVibration.startSequential();
while ("-v".equals(getNextOption())) {
int vibratorId = Integer.parseInt(getNextArgRequired());
combination.addNext(vibratorId, nextEffect());
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 376595b95c9d..5b4e6a032050 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -218,6 +218,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_SOLID_COLOR;
+import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_WALLPAPER;
import static com.android.server.wm.WindowManagerService.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
@@ -560,6 +561,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// The locusId associated with this activity, if set.
private LocusId mLocusId;
+ // Whether the activity was launched from a bubble.
+ private boolean mLaunchedFromBubble;
+
private SizeConfigurationBuckets mSizeConfigurations;
/**
@@ -601,8 +605,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
/** Whether our surface was set to be showing in the last call to {@link #prepareSurfaces} */
private boolean mLastSurfaceShowing = true;
- private Letterbox mLetterbox;
-
/**
* The activity is opaque and fills the entire space of this task.
* @see WindowContainer#fillsParent()
@@ -640,6 +642,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
*/
private boolean mWillCloseOrEnterPip;
+ private Letterbox mLetterbox;
+
/**
* The scale to fit at least one side of the activity to its parent. If the activity uses
* 1920x1080, and the actually size on the screen is 960x540, then the scale is 0.5.
@@ -667,6 +671,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
@Nullable
private Rect mLetterboxBoundsForFixedOrientationAndAspectRatio;
+ private boolean mShowWallpaperForLetterboxBackground;
+
// activity is not displayed?
// TODO: rename to mNoDisplay
@VisibleForTesting
@@ -1119,6 +1125,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
getLetterboxBackgroundColor().toArgb()));
pw.println(prefix + " letterboxBackgroundType="
+ letterboxBackgroundTypeToString(mWmService.getLetterboxBackgroundType()));
+ if (mWmService.getLetterboxBackgroundType() == LETTERBOX_BACKGROUND_WALLPAPER) {
+ pw.println(prefix + " isLetterboxWallpaperBlurSupported="
+ + isLetterboxWallpaperBlurSupported());
+ pw.println(prefix + " letterboxBackgroundWallpaperDarkScrimAlpha="
+ + getLetterboxWallpaperDarkScrimAlpha());
+ pw.println(prefix + " letterboxBackgroundWallpaperBlurRadius="
+ + getLetterboxWallpaperBlurRadius());
+ }
}
/**
@@ -1406,6 +1420,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
}
+ // TODO(b/183754168): Move letterbox UI logic into a separate class.
void layoutLetterbox(WindowState winHint) {
final WindowState w = findMainWindow();
if (w == null || winHint != null && w != winHint) {
@@ -1415,12 +1430,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|| w.isDragResizeChanged(); // Waiting for relayoutWindow to call preserveSurface.
final boolean needsLetterbox = surfaceReady && isLetterboxed(w);
updateRoundedCorners(w);
+ updateWallpaperForLetterbox(w);
if (needsLetterbox) {
if (mLetterbox == null) {
mLetterbox = new Letterbox(() -> makeChildSurface(null),
mWmService.mTransactionFactory,
mWmService::isLetterboxActivityCornersRounded,
- this::getLetterboxBackgroundColor);
+ this::getLetterboxBackgroundColor,
+ this::hasWallpaperBackgroudForLetterbox,
+ this::getLetterboxWallpaperBlurRadius,
+ this::getLetterboxWallpaperDarkScrimAlpha);
mLetterbox.attachInput(w);
}
getPosition(mTmpPoint);
@@ -1452,17 +1471,31 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (taskDescription != null && taskDescription.getBackgroundColorFloating() != 0) {
return Color.valueOf(taskDescription.getBackgroundColorFloating());
}
- return mWmService.getLetterboxBackgroundColor();
+ break;
case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND:
if (taskDescription != null && taskDescription.getBackgroundColor() != 0) {
return Color.valueOf(taskDescription.getBackgroundColor());
}
- // Falling through
+ break;
+ case LETTERBOX_BACKGROUND_WALLPAPER:
+ if (hasWallpaperBackgroudForLetterbox()) {
+ // Color is used for translucent scrim that dims wallpaper.
+ return Color.valueOf(Color.BLACK);
+ }
+ Slog.w(TAG, "Wallpaper option is selected for letterbox background but "
+ + "blur is not supported by a device or not supported in the current "
+ + "window configuration or both alpha scrim and blur radius aren't "
+ + "provided so using solid color background");
+ break;
case LETTERBOX_BACKGROUND_SOLID_COLOR:
return mWmService.getLetterboxBackgroundColor();
+ default:
+ throw new AssertionError(
+ "Unexpected letterbox background type: " + letterboxBackgroundType);
}
- throw new AssertionError(
- "Unexpected letterbox background type: " + letterboxBackgroundType);
+ // If picked option configured incorrectly or not supported then default to a solid color
+ // background.
+ return mWmService.getLetterboxBackgroundColor();
}
/**
@@ -1494,6 +1527,45 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
}
+ boolean hasWallpaperBackgroudForLetterbox() {
+ return mShowWallpaperForLetterboxBackground;
+ }
+
+ private void updateWallpaperForLetterbox(WindowState mainWindow) {
+ @LetterboxBackgroundType int letterboxBackgroundType =
+ mWmService.getLetterboxBackgroundType();
+ boolean wallpaperShouldBeShown =
+ letterboxBackgroundType == LETTERBOX_BACKGROUND_WALLPAPER
+ && isLetterboxed(mainWindow)
+ // Don't use wallpaper as a background if letterboxed for display cutout.
+ && !mainWindow.isLetterboxedForDisplayCutout()
+ // Check that dark scrim alpha or blur radius are provided
+ && (getLetterboxWallpaperBlurRadius() > 0
+ || getLetterboxWallpaperDarkScrimAlpha() > 0)
+ // Check that blur is supported by a device if blur radius is provided.
+ && (getLetterboxWallpaperBlurRadius() <= 0
+ || isLetterboxWallpaperBlurSupported());
+ if (mShowWallpaperForLetterboxBackground != wallpaperShouldBeShown) {
+ mShowWallpaperForLetterboxBackground = wallpaperShouldBeShown;
+ requestUpdateWallpaperIfNeeded();
+ }
+ }
+
+ private int getLetterboxWallpaperBlurRadius() {
+ int blurRadius = mWmService.getLetterboxBackgroundWallpaperBlurRadius();
+ return blurRadius < 0 ? 0 : blurRadius;
+ }
+
+ private float getLetterboxWallpaperDarkScrimAlpha() {
+ float alpha = mWmService.getLetterboxBackgroundWallpaperDarkScrimAlpha();
+ // No scrim by default.
+ return (alpha < 0 || alpha >= 1) ? 0.0f : alpha;
+ }
+
+ private boolean isLetterboxWallpaperBlurSupported() {
+ return mWmService.mContext.getSystemService(WindowManager.class).isCrossWindowBlurEnabled();
+ }
+
void updateLetterboxSurface(WindowState winHint) {
final WindowState w = findMainWindow();
if (w != winHint && winHint != null && w != null) {
@@ -4149,7 +4221,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
}
+ boolean getLaunchedFromBubble() {
+ return mLaunchedFromBubble;
+ }
+
private void setOptions(@NonNull ActivityOptions options) {
+ mLaunchedFromBubble = options.getLaunchedFromBubble();
mPendingOptions = options;
if (options.getAnimationType() == ANIM_REMOTE_ANIMATION) {
mPendingRemoteAnimation = options.getRemoteAnimationAdapter();
@@ -6939,12 +7016,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
newParentConfiguration = mTmpConfig;
}
- final int windowingMode = getWindowingMode();
+ // Can't use resolvedConfig.windowConfiguration.getWindowingMode() because it can be
+ // different from windowing mode of the task (PiP) during transition from fullscreen to PiP
+ // and back which can cause visible issues (see b/184078928).
+ final int parentWindowingMode =
+ newParentConfiguration.windowConfiguration.getWindowingMode();
// TODO(b/181207944): Consider removing the if condition and always run
// resolveFixedOrientationConfiguration() since this should be applied for all cases.
- if (isSplitScreenWindowingMode(windowingMode)
- || windowingMode == WINDOWING_MODE_MULTI_WINDOW
- || windowingMode == WINDOWING_MODE_FULLSCREEN) {
+ if (isSplitScreenWindowingMode(parentWindowingMode)
+ || parentWindowingMode == WINDOWING_MODE_MULTI_WINDOW
+ || parentWindowingMode == WINDOWING_MODE_FULLSCREEN) {
resolveFixedOrientationConfiguration(newParentConfiguration);
}
@@ -7349,6 +7430,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
getPid(), info.applicationInfo.uid) == PERMISSION_GRANTED) {
return false;
}
+ // Do not sandbox to activity window bounds if the feature is disabled.
+ if (mDisplayContent != null && !mDisplayContent.sandboxDisplayApis()) {
+ return false;
+ }
// Max bounds should be sandboxed where an activity is letterboxed (activity bounds will be
// smaller than task bounds).
if (!matchParentBounds()) {
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index aa1f42ecd853..75a188ed86a2 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2633,6 +2633,12 @@ class ActivityStarter {
mOptions = null;
}
}
+
+ if (mPreferredWindowingMode != WINDOWING_MODE_UNDEFINED
+ && intentTask.getWindowingMode() != mPreferredWindowingMode) {
+ intentTask.setWindowingMode(mPreferredWindowingMode);
+ }
+
// Need to update mTargetRootTask because if task was moved out of it, the original root
// task may be destroyed.
mTargetRootTask = intentActivity.getRootTask();
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 7ae42cc9396a..a0beee4afcb9 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -35,9 +35,7 @@ import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
@@ -114,7 +112,6 @@ import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_O
import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_ONLY;
import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS;
import static com.android.server.wm.Task.REPARENT_KEEP_ROOT_TASK_AT_FRONT;
-import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
import android.Manifest;
@@ -147,7 +144,6 @@ import android.app.PictureInPictureParams;
import android.app.ProfilerInfo;
import android.app.RemoteAction;
import android.app.WaitResult;
-import android.app.WindowConfiguration;
import android.app.admin.DevicePolicyCache;
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
@@ -227,7 +223,6 @@ import android.view.WindowManager;
import android.window.IWindowOrganizerController;
import android.window.SplashScreenView.SplashScreenViewParcelable;
import android.window.TaskSnapshot;
-import android.window.WindowContainerTransaction;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
@@ -1897,57 +1892,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
return null;
}
- @Override
- public boolean setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
- enforceTaskPermission("setTaskWindowingMode()");
- synchronized (mGlobalLock) {
- final long ident = Binder.clearCallingIdentity();
- try {
- if (isInLockTaskMode() && windowingMode != WINDOWING_MODE_FULLSCREEN) {
- Slog.w(TAG, "setTaskWindowingMode: Is in lock task mode="
- + getLockTaskModeState());
- return false;
- }
-
- if (WindowConfiguration.isSplitScreenWindowingMode(windowingMode)) {
- return setTaskWindowingModeSplitScreen(taskId, windowingMode, toTop);
- }
- final Task task = mRootWindowContainer.anyTaskForId(taskId,
- MATCH_ATTACHED_TASK_ONLY);
- if (task == null) {
- Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
- return false;
- }
-
- ProtoLog.d(WM_DEBUG_TASKS, "setTaskWindowingMode: moving task=%d "
- + "to windowingMode=%d toTop=%b", taskId, windowingMode, toTop);
-
- if (!task.isActivityTypeStandardOrUndefined()) {
- throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
- + " non-standard task " + taskId + " to windowing mode="
- + windowingMode);
- }
-
- final Task rootTask = task.getRootTask();
- if (toTop) {
- rootTask.moveToFront("setTaskWindowingMode", task);
- }
- // Convert some windowing-mode changes into root-task reparents for split-screen.
- if (rootTask.inSplitScreenWindowingMode()) {
- rootTask.getDisplayArea().onSplitScreenModeDismissed();
-
- } else {
- rootTask.setWindowingMode(windowingMode);
- rootTask.mDisplayContent.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS,
- true /* notifyClients */);
- }
- return true;
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
/**
* Sets the locusId for a particular activity.
*
@@ -2225,59 +2169,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
/**
- * Moves the specified task into a split-screen tile.
- */
- private boolean setTaskWindowingModeSplitScreen(int taskId, int windowingMode, boolean toTop) {
- if (!WindowConfiguration.isSplitScreenWindowingMode(windowingMode)) {
- throw new IllegalArgumentException("Calling setTaskWindowingModeSplitScreen with non"
- + "split-screen mode: " + windowingMode);
- }
-
- final Task task = mRootWindowContainer.anyTaskForId(taskId,
- MATCH_ATTACHED_TASK_ONLY);
- if (task == null) {
- Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
- return false;
- }
- if (!task.isActivityTypeStandardOrUndefined()) {
- throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
- + " non-standard task " + taskId + " to split-screen windowing mode");
- }
- if (!task.supportsSplitScreenWindowingMode()) {
- return false;
- }
-
- final int prevMode = task.getWindowingMode();
- if (prevMode == windowingMode) {
- // The task is already in split-screen and with correct windowing mode.
- return true;
- }
-
- moveTaskToSplitScreenPrimaryTask(task, toTop);
- return prevMode != task.getWindowingMode();
- }
-
- void moveTaskToSplitScreenPrimaryTask(Task task, boolean toTop) {
- final TaskDisplayArea taskDisplayArea = task.getDisplayArea();
- final Task primarySplitTask = taskDisplayArea.getRootSplitScreenPrimaryTask();
- if (primarySplitTask == null) {
- throw new IllegalStateException("Can't enter split without associated organized task");
- }
-
- if (toTop) {
- taskDisplayArea.positionChildAt(POSITION_TOP, primarySplitTask,
- false /* includingParents */);
- }
- WindowContainerTransaction wct = new WindowContainerTransaction();
- // Clear out current windowing mode before reparenting to split taks.
- wct.setWindowingMode(
- task.getRootTask().mRemoteToken.toWindowContainerToken(), WINDOWING_MODE_UNDEFINED);
- wct.reparent(task.getRootTask().mRemoteToken.toWindowContainerToken(),
- primarySplitTask.mRemoteToken.toWindowContainerToken(), toTop);
- mWindowOrganizerController.applyTransaction(wct);
- }
-
- /**
* Removes root tasks in the input windowing modes from the system if they are of activity type
* ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
*/
@@ -3400,47 +3291,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
return true;
}
- // TODO(b/149338177): remove when CTS no-longer requires it
- @Override
- public void resizePrimarySplitScreen(Rect dockedBounds, Rect tempDockedTaskBounds,
- Rect tempDockedTaskInsetBounds,
- Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
- enforceTaskPermission("resizePrimarySplitScreen()");
- final long ident = Binder.clearCallingIdentity();
- try {
- synchronized (mGlobalLock) {
- final TaskDisplayArea tc = mRootWindowContainer.getDefaultTaskDisplayArea();
- final Task primary = tc.getRootSplitScreenPrimaryTask();
- final Task secondary = tc.getTask(t -> t.mCreatedByOrganizer && t.isRootTask()
- && t.inSplitScreenSecondaryWindowingMode());
- if (primary == null || secondary == null) {
- return;
- }
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- final Rect primaryRect =
- tempDockedTaskInsetBounds != null ? tempDockedTaskInsetBounds
- : (tempDockedTaskBounds != null ? tempDockedTaskBounds
- : dockedBounds);
- wct.setBounds(primary.mRemoteToken.toWindowContainerToken(), primaryRect);
- Rect otherRect = tempOtherTaskInsetBounds != null ? tempOtherTaskInsetBounds
- : tempOtherTaskBounds;
- if (otherRect == null) {
- // Temporary estimation... again this is just for tests.
- otherRect = new Rect(secondary.getBounds());
- if (tc.getBounds().width() > tc.getBounds().height()) {
- otherRect.left = primaryRect.right + 6;
- } else {
- otherRect.top = primaryRect.bottom + 6;
- }
- }
- wct.setBounds(secondary.mRemoteToken.toWindowContainerToken(), otherRect);
- mWindowOrganizerController.applyTransaction(wct);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
@Override
public void setSplitScreenResizing(boolean resizing) {
enforceTaskPermission("setSplitScreenResizing()");
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index bfbc10aee7a7..bdde3692ef53 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -826,7 +826,8 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
r.takeOptions(), dc.isNextTransitionForward(),
proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
- r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken));
+ r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken,
+ r.getLaunchedFromBubble()));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 9ca7eca07dc6..9a43ca8794da 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -16,7 +16,6 @@
package com.android.server.wm;
-import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_APP_CRASHED;
@@ -128,7 +127,7 @@ public class AppTransitionController {
final ArraySet<WindowContainer> openingWcs = getAnimationTargets(
mDisplayContent.mOpeningApps, mDisplayContent.mClosingApps, true /* visible */);
final boolean showWallpaper = wallpaperTarget != null
- && ((wallpaperTarget.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0
+ && (wallpaperTarget.hasWallpaper()
// Update task open transition to wallpaper transition when wallpaper is visible.
// (i.e.launching app info activity from recent tasks)
|| ((firstTransit == TRANSIT_OPEN || firstTransit == TRANSIT_TO_FRONT)
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index b1606c9e5d2d..4b735c2c218e 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -61,7 +61,6 @@ import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
@@ -349,6 +348,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
int mBaseDisplayWidth = 0;
int mBaseDisplayHeight = 0;
boolean mIsSizeForced = false;
+
+ /**
+ * Overridden display size and metrics to activity window bounds. Set via
+ * "adb shell wm set-sandbox-display-apis". Default to true, since only disable for debugging.
+ * @see WindowManagerService#setSandboxDisplayApis(int, boolean)
+ */
+ private boolean mSandboxDisplayApis = true;
+
/**
* Overridden display density for current user. Initialized with {@link #mInitialDisplayDensity}
* but can be set from Settings or via shell command "adb shell wm density".
@@ -913,7 +920,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// Take care of the window being ready to display.
final boolean committed = winAnimator.commitFinishDrawingLocked();
if (isDefaultDisplay && committed) {
- if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
+ if (w.hasWallpaper()) {
if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
"First draw done in potential wallpaper target " + w);
mWallpaperMayChange = true;
@@ -5737,6 +5744,21 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return true;
}
+ /**
+ * Sets if Display APIs should be sandboxed to the activity window bounds.
+ */
+ void setSandboxDisplayApis(boolean sandboxDisplayApis) {
+ mSandboxDisplayApis = sandboxDisplayApis;
+ }
+
+ /**
+ * Returns {@code true} is Display APIs should be sandboxed to the activity window bounds,
+ * {@code false} otherwise. Default to true, unless set for debugging purposes.
+ */
+ boolean sandboxDisplayApis() {
+ return mSandboxDisplayApis;
+ }
+
/** The entry for proceeding to handle {@link #mFixedRotationLaunchingApp}. */
class FixedRotationTransitionListener extends WindowManagerInternal.AppTransitionListener {
diff --git a/services/core/java/com/android/server/wm/FadeRotationAnimationController.java b/services/core/java/com/android/server/wm/FadeRotationAnimationController.java
index 5ee692806349..b14d4a1e4b5a 100644
--- a/services/core/java/com/android/server/wm/FadeRotationAnimationController.java
+++ b/services/core/java/com/android/server/wm/FadeRotationAnimationController.java
@@ -39,6 +39,9 @@ public class FadeRotationAnimationController extends FadeAnimationController {
private final Runnable mFrozenTimeoutRunnable;
private final WindowToken mNavBarToken;
+ /** A runnable which gets called when the {@link #show()} is called. */
+ private Runnable mOnShowRunnable;
+
public FadeRotationAnimationController(DisplayContent displayContent) {
super(displayContent);
mService = displayContent.mWmService;
@@ -81,6 +84,10 @@ public class FadeRotationAnimationController extends FadeAnimationController {
if (mFrozenTimeoutRunnable != null) {
mService.mH.removeCallbacks(mFrozenTimeoutRunnable);
}
+ if (mOnShowRunnable != null) {
+ mOnShowRunnable.run();
+ mOnShowRunnable = null;
+ }
}
/**
@@ -115,6 +122,10 @@ public class FadeRotationAnimationController extends FadeAnimationController {
return token == mNavBarToken || mTargetWindowTokens.contains(token);
}
+ void setOnShowRunnable(Runnable onShowRunnable) {
+ mOnShowRunnable = onShowRunnable;
+ }
+
@Override
public Animation getFadeInAnimation() {
if (mFrozenTimeoutRunnable != null) {
diff --git a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
index 567b6c2b964e..b94bc5b2c61d 100644
--- a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
+++ b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
@@ -390,7 +390,7 @@ public class ImmersiveModeConfirmation {
final Bundle options = getOptionsForWindowContext(rootDisplayAreaId);
final IWindowManager wms = WindowManagerGlobal.getWindowManagerService();
try {
- wms.registerWindowContextListener(mWindowContext.getWindowContextToken(),
+ wms.attachWindowContextToDisplayArea(mWindowContext.getWindowContextToken(),
IMMERSIVE_MODE_CONFIRMATION_WINDOW_TYPE, mContext.getDisplayId(), options);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 073231401715..7daebff2ccc2 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -84,6 +84,7 @@ class InsetsSourceProvider {
private TriConsumer<DisplayFrames, WindowState, Rect> mImeFrameProvider;
private final Rect mImeOverrideFrame = new Rect();
private boolean mIsLeashReadyForDispatching;
+ private final Rect mLastSourceFrame = new Rect();
private final Consumer<Transaction> mSetLeashPositionConsumer = t -> {
if (mControl != null) {
@@ -268,11 +269,14 @@ class InsetsSourceProvider {
mSetLeashPositionConsumer.accept(mWin.getPendingTransaction());
}
}
- final Insets insetsHint = mSource.calculateInsets(
- mWin.getBounds(), true /* ignoreVisibility */);
- if (!insetsHint.equals(mControl.getInsetsHint())) {
- changed = true;
- mControl.setInsetsHint(insetsHint);
+ if (mServerVisible && !mLastSourceFrame.equals(mSource.getFrame())) {
+ final Insets insetsHint = mSource.calculateInsets(
+ mWin.getBounds(), true /* ignoreVisibility */);
+ if (!insetsHint.equals(mControl.getInsetsHint())) {
+ changed = true;
+ mControl.setInsetsHint(insetsHint);
+ }
+ mLastSourceFrame.set(mSource.getFrame());
}
if (changed) {
mStateController.notifyControlChanged(mControlTarget);
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index 377e4989f65f..af82f755152c 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -47,6 +47,10 @@ public class Letterbox {
private final Supplier<SurfaceControl.Transaction> mTransactionFactory;
private final Supplier<Boolean> mAreCornersRounded;
private final Supplier<Color> mColorSupplier;
+ // Parameters for "blurred wallpaper" letterbox background.
+ private final Supplier<Boolean> mHasWallpaperBackgroundSupplier;
+ private final Supplier<Integer> mBlurRadiusSupplier;
+ private final Supplier<Float> mDarkScrimAlphaSupplier;
private final Rect mOuter = new Rect();
private final Rect mInner = new Rect();
@@ -68,11 +72,17 @@ public class Letterbox {
public Letterbox(Supplier<SurfaceControl.Builder> surfaceControlFactory,
Supplier<SurfaceControl.Transaction> transactionFactory,
Supplier<Boolean> areCornersRounded,
- Supplier<Color> colorSupplier) {
+ Supplier<Color> colorSupplier,
+ Supplier<Boolean> hasWallpaperBackgroundSupplier,
+ Supplier<Integer> blurRadiusSupplier,
+ Supplier<Float> darkScrimAlphaSupplier) {
mSurfaceControlFactory = surfaceControlFactory;
mTransactionFactory = transactionFactory;
mAreCornersRounded = areCornersRounded;
mColorSupplier = colorSupplier;
+ mHasWallpaperBackgroundSupplier = hasWallpaperBackgroundSupplier;
+ mBlurRadiusSupplier = blurRadiusSupplier;
+ mDarkScrimAlphaSupplier = darkScrimAlphaSupplier;
}
/**
@@ -180,7 +190,7 @@ public class Letterbox {
return true;
}
}
- if (mBehind.needsApplySurfaceChanges()) {
+ if (mAreCornersRounded.get() && mBehind.needsApplySurfaceChanges()) {
return true;
}
return false;
@@ -274,6 +284,7 @@ public class Letterbox {
private final String mType;
private SurfaceControl mSurface;
private Color mColor;
+ private boolean mHasWallpaperBackground;
private final Rect mSurfaceFrameRelative = new Rect();
private final Rect mLayoutFrameGlobal = new Rect();
@@ -351,15 +362,14 @@ public class Letterbox {
}
mColor = mColorSupplier.get();
- final float[] rgbTmpFloat = new float[3];
- rgbTmpFloat[0] = mColor.red();
- rgbTmpFloat[1] = mColor.green();
- rgbTmpFloat[2] = mColor.blue();
- t.setColor(mSurface, rgbTmpFloat);
-
+ t.setColor(mSurface, getRgbColorArray());
t.setPosition(mSurface, mSurfaceFrameRelative.left, mSurfaceFrameRelative.top);
t.setWindowCrop(mSurface, mSurfaceFrameRelative.width(),
mSurfaceFrameRelative.height());
+
+ mHasWallpaperBackground = mHasWallpaperBackgroundSupplier.get();
+ updateAlphaAndBlur(t);
+
t.show(mSurface);
} else if (mSurface != null) {
t.hide(mSurface);
@@ -370,9 +380,43 @@ public class Letterbox {
}
}
+ private void updateAlphaAndBlur(SurfaceControl.Transaction t) {
+ if (!mHasWallpaperBackground) {
+ // Opaque
+ t.setAlpha(mSurface, 1.0f);
+ // Removing pre-exesting blur
+ t.setBackgroundBlurRadius(mSurface, 0);
+ return;
+ }
+ final float alpha = mDarkScrimAlphaSupplier.get();
+ t.setAlpha(mSurface, alpha);
+
+ // Translucent dark scrim can be shown without blur.
+ if (mBlurRadiusSupplier.get() <= 0) {
+ // Removing pre-exesting blur
+ t.setBackgroundBlurRadius(mSurface, 0);
+ return;
+ }
+
+ t.setBackgroundBlurRadius(mSurface, mBlurRadiusSupplier.get());
+ }
+
+ private float[] getRgbColorArray() {
+ final float[] rgbTmpFloat = new float[3];
+ rgbTmpFloat[0] = mColor.red();
+ rgbTmpFloat[1] = mColor.green();
+ rgbTmpFloat[2] = mColor.blue();
+ return rgbTmpFloat;
+ }
+
public boolean needsApplySurfaceChanges() {
return !mSurfaceFrameRelative.equals(mLayoutFrameRelative)
- || mColorSupplier.get() != mColor;
+ // If mSurfaceFrameRelative is empty then mHasWallpaperBackground and mColor
+ // may never be updated in applySurfaceChanges but this doesn't mean that
+ // update is needed.
+ || !mSurfaceFrameRelative.isEmpty()
+ && (mHasWallpaperBackgroundSupplier.get() != mHasWallpaperBackground
+ || !mColorSupplier.get().equals(mColor));
}
}
}
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 20c0d4189ad8..6631a3e61e77 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -58,8 +58,6 @@ import android.content.pm.ParceledListSlice;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
-import android.graphics.Point;
-import android.graphics.Rect;
import android.os.Environment;
import android.os.IBinder;
import android.os.RemoteException;
@@ -1345,6 +1343,7 @@ class RecentTasks {
+ " inactiveDuration=" + task.getInactiveDuration()
+ " activityType=" + task.getActivityType()
+ " windowingMode=" + task.getWindowingMode()
+ + " isAlwaysOnTopWhenVisible=" + task.isAlwaysOnTopWhenVisible()
+ " intentFlags=" + task.getBaseIntent().getFlags());
}
@@ -1380,7 +1379,7 @@ class RecentTasks {
break;
case WINDOWING_MODE_MULTI_WINDOW:
// Ignore tasks that are always on top
- if (task.isAlwaysOnTop()) {
+ if (task.isAlwaysOnTopWhenVisible()) {
return false;
}
break;
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index c1d5b5c98f57..129a6ce8e1d5 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -669,21 +669,33 @@ public class RecentsAnimationController implements DeathRecipient {
}
navWindow.setSurfaceTranslationY(0);
- if (navWindow.mToken == null) {
+ final WindowToken navToken = navWindow.mToken;
+ if (navToken == null) {
return;
}
final SurfaceControl.Transaction t = mDisplayContent.getPendingTransaction();
- final WindowContainer parent = navWindow.mToken.getParent();
- // Reparent the SurfaceControl of nav bar token back.
- t.reparent(navWindow.mToken.getSurfaceControl(), parent.getSurfaceControl());
-
+ final WindowContainer parent = navToken.getParent();
if (animate) {
- // Run fade-in animation to show navigation bar back to bottom of the display.
- final NavBarFadeAnimationController controller =
+ final NavBarFadeAnimationController navBarFadeAnimationController =
mDisplayContent.getDisplayPolicy().getNavBarFadeAnimationController();
- if (controller != null) {
- controller.fadeWindowToken(true);
+ final Runnable fadeInAnim = () -> {
+ // Reparent the SurfaceControl of nav bar token back.
+ t.reparent(navToken.getSurfaceControl(), parent.getSurfaceControl());
+ // Run fade-in animation to show navigation bar back to bottom of the display.
+ if (navBarFadeAnimationController != null) {
+ navBarFadeAnimationController.fadeWindowToken(true);
+ }
+ };
+ final FadeRotationAnimationController fadeRotationAnimationController =
+ mDisplayContent.getFadeRotationAnimationController();
+ if (fadeRotationAnimationController != null) {
+ fadeRotationAnimationController.setOnShowRunnable(fadeInAnim);
+ } else {
+ fadeInAnim.run();
}
+ } else {
+ // Reparent the SurfaceControl of nav bar token back.
+ t.reparent(navToken.getSurfaceControl(), parent.getSurfaceControl());
}
}
diff --git a/services/core/java/com/android/server/wm/SafeActivityOptions.java b/services/core/java/com/android/server/wm/SafeActivityOptions.java
index 65671959e884..c9d5fa473ea8 100644
--- a/services/core/java/com/android/server/wm/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/wm/SafeActivityOptions.java
@@ -18,6 +18,7 @@ package com.android.server.wm;
import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
+import static android.Manifest.permission.STATUS_BAR_SERVICE;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -278,6 +279,19 @@ public class SafeActivityOptions {
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
+
+ // If launched from bubble is specified, then ensure that the caller is system or sysui.
+ if (options.getLaunchedFromBubble() && callingUid != Process.SYSTEM_UID) {
+ final int statusBarPerm = ActivityTaskManagerService.checkPermission(
+ STATUS_BAR_SERVICE, callingPid, callingUid);
+ if (statusBarPerm == PERMISSION_DENIED) {
+ final String msg = "Permission Denial: starting " + getIntentString(intent)
+ + " from " + callerApp + " (pid=" + callingPid
+ + ", uid=" + callingUid + ") with launchedFromBubble=true";
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
+ }
+ }
}
private String getIntentString(Intent intent) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index c293a159ec4b..86904991616f 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -5277,6 +5277,13 @@ class Task extends WindowContainer<WindowContainer> {
}
/**
+ * @return whether this task is always on top without taking visibility into account.
+ */
+ public boolean isAlwaysOnTopWhenVisible() {
+ return super.isAlwaysOnTop();
+ }
+
+ /**
* Returns whether this task is currently forced to be hidden for any reason.
*/
protected boolean isForceHidden() {
@@ -5398,16 +5405,6 @@ class Task extends WindowContainer<WindowContainer> {
// Nothing else to do if we don't have a window container yet. E.g. call from ctor.
return;
}
-
- if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && alreadyInSplitScreenMode) {
- // We already have a root split-screen task in this display, so just move the
- // tasks over.
- // TODO: Figure-out how to do all the stuff in
- // AMS.setTaskWindowingModeSplitScreenPrimary
- throw new IllegalArgumentException("Setting primary split-screen windowing mode"
- + " while there is already one isn't currently supported");
- //return;
- }
} finally {
mAtmService.continueWindowLayout();
}
@@ -5534,7 +5531,7 @@ class Task extends WindowContainer<WindowContainer> {
mCurrentUser = userId;
super.switchUser(userId);
- if (isLeafTask() && showToCurrentUser()) {
+ if (!isRootTask() && showToCurrentUser()) {
getParent().positionChildAt(POSITION_TOP, this, false /*includeParents*/);
}
}
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 5af44317b8c1..5ffab483202f 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -16,8 +16,6 @@
package com.android.server.wm;
-import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
-
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -292,7 +290,7 @@ class TaskSnapshotController {
builder.setContentInsets(contentInsets);
final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE;
- final boolean isShowWallpaper = (mainWindow.getAttrs().flags & FLAG_SHOW_WALLPAPER) != 0;
+ final boolean isShowWallpaper = mainWindow.hasWallpaper();
if (pixelFormat == PixelFormat.UNKNOWN) {
pixelFormat = mPersister.use16BitFormat() && activity.fillsParent()
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 75be444567ff..e4ac1f6c5b50 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -31,6 +31,7 @@ import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
+import static android.view.WindowManager.transitTypeToString;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
@@ -403,7 +404,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
sb.append("TransitionRecord{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
sb.append(" id=" + mSyncId);
- sb.append(" type=" + mType);
+ sb.append(" type=" + transitTypeToString(mType));
sb.append(" flags=" + mFlags);
sb.append('}');
return sb.toString();
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 580bd06194c8..5635c33995b1 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -18,7 +18,6 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
@@ -178,8 +177,7 @@ class WallpaperController {
final boolean animationWallpaper = animatingContainer != null
&& animatingContainer.getAnimation() != null
&& animatingContainer.getAnimation().getShowWallpaper();
- final boolean hasWallpaper = (w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0
- || animationWallpaper;
+ final boolean hasWallpaper = w.hasWallpaper() || animationWallpaper;
final boolean isRecentsTransitionTarget = (recentsAnimationController != null
&& recentsAnimationController.isWallpaperVisible(w));
if (isRecentsTransitionTarget) {
diff --git a/services/core/java/com/android/server/wm/WindowContextListenerController.java b/services/core/java/com/android/server/wm/WindowContextListenerController.java
index 8b08314136d4..5e75996b0012 100644
--- a/services/core/java/com/android/server/wm/WindowContextListenerController.java
+++ b/services/core/java/com/android/server/wm/WindowContextListenerController.java
@@ -103,7 +103,11 @@ class WindowContextListenerController {
listener.unregister();
}
- boolean assertCallerCanRemoveListener(IBinder clientToken, boolean callerCanManageAppTokens,
+ /**
+ * Verifies if the caller is allowed to do the operation to the listener specified by
+ * {@code clientToken}.
+ */
+ boolean assertCallerCanModifyListener(IBinder clientToken, boolean callerCanManageAppTokens,
int callingUid) {
final WindowContextListenerImpl listener = mListeners.get(clientToken);
if (listener == null) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c23cc2e709c0..43dceeda3026 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -56,6 +56,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
+import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
@@ -451,14 +452,6 @@ public class WindowManagerService extends IWindowManager.Stub
private static final int ANIMATION_COMPLETED_TIMEOUT_MS = 5000;
- /**
- * Override of aspect ratio for fixed orientation letterboxing that is set via ADB with
- * set-fixed-orientation-letterbox-aspect-ratio or via {@link
- * com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio} will be ignored
- * if it is <= this value.
- */
- static final float MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO = 1.0f;
-
@VisibleForTesting
WindowManagerConstants mConstants;
@@ -984,14 +977,18 @@ public class WindowManagerService extends IWindowManager.Stub
private boolean mAnimationsDisabled = false;
boolean mPointerLocationEnabled = false;
- // Aspect ratio of letterbox for fixed orientation, values <=
- // MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO will be ignored.
- private volatile float mFixedOrientationLetterboxAspectRatio;
+ /**
+ * Override of aspect ratio for fixed orientation letterboxing that is set via ADB with
+ * set-fixed-orientation-letterbox-aspect-ratio or via {@link
+ * com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio} will be ignored
+ * if it is <= this value.
+ */
+ static final float MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO = 1.0f;
/** Enum for Letterbox background type. */
@Retention(RetentionPolicy.SOURCE)
@IntDef({LETTERBOX_BACKGROUND_SOLID_COLOR, LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND,
- LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING})
+ LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING, LETTERBOX_BACKGROUND_WALLPAPER})
@interface LetterboxBackgroundType {};
/** Solid background using color specified in R.color.config_letterboxBackgroundColor. */
static final int LETTERBOX_BACKGROUND_SOLID_COLOR = 0;
@@ -1002,14 +999,30 @@ public class WindowManagerService extends IWindowManager.Stub
/** Color specified in R.attr.colorBackgroundFloating for the letterboxed application. */
static final int LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING = 2;
+ /** Using wallpaper as a background which can be blurred or dimmed with dark scrim. */
+ static final int LETTERBOX_BACKGROUND_WALLPAPER = 3;
+
+ // Aspect ratio of letterbox for fixed orientation, values <=
+ // MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO will be ignored.
+ private float mFixedOrientationLetterboxAspectRatio;
+
// Corners radius for activities presented in the letterbox mode, values < 0 will be ignored.
- private volatile int mLetterboxActivityCornersRadius;
+ private int mLetterboxActivityCornersRadius;
// Color for {@link #LETTERBOX_BACKGROUND_SOLID_COLOR} letterbox background type.
- private volatile Color mLetterboxBackgroundColor;
+ private Color mLetterboxBackgroundColor;
@LetterboxBackgroundType
- private volatile int mLetterboxBackgroundType;
+ private int mLetterboxBackgroundType;
+
+ // Blur radius for LETTERBOX_BACKGROUND_WALLPAPER option in mLetterboxBackgroundType.
+ // Values <= 0 are ignored and 0 is used instead.
+ private int mLetterboxBackgroundWallpaperBlurRadius;
+
+ // Alpha of a black scrim shown over wallpaper letterbox background when
+ // LETTERBOX_BACKGROUND_WALLPAPER option is selected for mLetterboxBackgroundType.
+ // Values < 0 or >= 1 are ignored and 0.0 (transparent) is used instead.
+ private float mLetterboxBackgroundWallpaperDarkScrimAlpha;
final InputManagerService mInputManager;
final DisplayManagerInternal mDisplayManagerInternal;
@@ -1244,6 +1257,10 @@ public class WindowManagerService extends IWindowManager.Stub
mLetterboxBackgroundColor = Color.valueOf(context.getResources().getColor(
com.android.internal.R.color.config_letterboxBackgroundColor));
mLetterboxBackgroundType = readLetterboxBackgroundTypeFromConfig(context);
+ mLetterboxBackgroundWallpaperBlurRadius = context.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius);
+ mLetterboxBackgroundWallpaperDarkScrimAlpha = context.getResources().getFloat(
+ com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha);
mInputManager = inputManager; // Must be before createDisplayContentLocked.
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
@@ -1783,7 +1800,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (type == TYPE_WALLPAPER) {
displayContent.mWallpaperController.clearLastWallpaperTimeoutTime();
displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
- } else if ((attrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
+ } else if (win.hasWallpaper()) {
displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
} else if (displayContent.mWallpaperController.isBelowWallpaperTarget(win)) {
// If there is currently a wallpaper being shown, and
@@ -2086,7 +2103,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (win.mAttrs.type == TYPE_WALLPAPER) {
dc.mWallpaperController.clearLastWallpaperTimeoutTime();
dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
- } else if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
+ } else if (win.hasWallpaper()) {
dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
}
@@ -2305,7 +2322,7 @@ public class WindowManagerService extends IWindowManager.Stub
|| (!win.mRelayoutCalled);
boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
- && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
+ && win.hasWallpaper();
wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
if ((flagChanges & FLAG_SECURE) != 0 && winAnimator.mSurfaceController != null) {
winAnimator.mSurfaceController.setSecure(win.isSecureLocked());
@@ -2458,29 +2475,12 @@ public class WindowManagerService extends IWindowManager.Stub
win.mResizedWhileGone = false;
}
- // We must always send the latest {@link MergedConfiguration}, regardless of whether we
- // have already reported it. The client might not have processed the previous value yet
- // and needs process it before handling the corresponding window frame. the variable
- // {@code mergedConfiguration} is an out parameter that will be passed back to the
- // client over IPC and checked there.
- // Note: in the cases where the window is tied to an activity, we should not send a
- // configuration update when the window has requested to be hidden. Doing so can lead
- // to the client erroneously accepting a configuration that would have otherwise caused
- // an activity restart. We instead hand back the last reported
- // {@link MergedConfiguration}.
- if (shouldRelayout && (!win.shouldCheckTokenVisibleRequested()
- || win.mToken.isVisibleRequested())) {
- win.getMergedConfiguration(mergedConfiguration);
- } else {
- win.getLastReportedMergedConfiguration(mergedConfiguration);
- }
-
- win.setLastReportedMergedConfiguration(mergedConfiguration);
+ win.fillClientWindowFramesAndConfiguration(outFrames, mergedConfiguration,
+ false /* useLatestConfig */, shouldRelayout);
// Set resize-handled here because the values are sent back to the client.
win.onResizeHandled();
- win.fillClientWindowFrames(outFrames);
outInsetsState.set(win.getCompatInsetsState(), win.isClientLocal());
if (DEBUG) {
Slog.v(TAG_WM, "Relayout given client " + client.asBinder()
@@ -2634,7 +2634,7 @@ public class WindowManagerService extends IWindowManager.Stub
ProtoLog.d(WM_DEBUG_ADD_REMOVE, "finishDrawingWindow: %s mDrawState=%s",
win, (win != null ? win.mWinAnimator.drawStateToString() : "null"));
if (win != null && win.finishDrawing(postDrawTransaction)) {
- if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
+ if (win.hasWallpaper()) {
win.getDisplayContent().pendingLayoutChanges |=
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
}
@@ -2701,30 +2701,19 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- /**
- * Registers a listener for a {@link android.window.WindowContext} to subscribe to configuration
- * changes of a {@link DisplayArea}.
- *
- * @param clientToken the window context's token
- * @param type Window type of the window context
- * @param displayId The display associated with the window context
- * @param options A bundle used to pass window-related options and choose the right DisplayArea
- *
- * @return {@code true} if the listener was registered successfully.
- */
@Override
- public boolean registerWindowContextListener(IBinder clientToken, int type, int displayId,
+ public boolean attachWindowContextToDisplayArea(IBinder clientToken, int type, int displayId,
Bundle options) {
final boolean callerCanManageAppTokens = checkCallingPermission(MANAGE_APP_TOKENS,
- "registerWindowContextListener", false /* printLog */);
+ "attachWindowContextToDisplayArea", false /* printLog */);
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
final DisplayContent dc = mRoot.getDisplayContentOrCreate(displayId);
if (dc == null) {
- ProtoLog.w(WM_ERROR, "registerWindowContextListener: trying to add listener to"
- + " a non-existing display:%d", displayId);
+ ProtoLog.w(WM_ERROR, "attachWindowContextToDisplayArea: trying to attach"
+ + " to a non-existing display:%d", displayId);
return false;
}
// TODO(b/155340867): Investigate if we still need roundedCornerOverlay after
@@ -2741,14 +2730,50 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
- public void unregisterWindowContextListener(IBinder clientToken) {
+ public void attachWindowContextToWindowToken(IBinder clientToken, IBinder token) {
+ final boolean callerCanManageAppTokens = checkCallingPermission(MANAGE_APP_TOKENS,
+ "attachWindowContextToWindowToken", false /* printLog */);
+ final int callingUid = Binder.getCallingUid();
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final WindowToken windowToken = mRoot.getWindowToken(token);
+ if (windowToken == null) {
+ ProtoLog.w(WM_ERROR, "Then token:%s is invalid. It might be "
+ + "removed", token);
+ return;
+ }
+ final int type = mWindowContextListenerController.getWindowType(clientToken);
+ if (type == INVALID_WINDOW_TYPE) {
+ throw new IllegalArgumentException("The clientToken:" + clientToken
+ + " should have been attached.");
+ }
+ if (type != windowToken.windowType) {
+ throw new IllegalArgumentException("The WindowToken's type should match"
+ + " the created WindowContext's type. WindowToken's type is "
+ + windowToken.windowType + ", while WindowContext's is " + type);
+ }
+ if (!mWindowContextListenerController.assertCallerCanModifyListener(clientToken,
+ callerCanManageAppTokens, callingUid)) {
+ return;
+ }
+ mWindowContextListenerController.registerWindowContainerListener(clientToken,
+ windowToken, callingUid, windowToken.windowType, windowToken.mOptions);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ @Override
+ public void detachWindowContextFromWindowContainer(IBinder clientToken) {
final boolean callerCanManageAppTokens = checkCallingPermission(MANAGE_APP_TOKENS,
- "unregisterWindowContextListener", false /* printLog */);
+ "detachWindowContextFromWindowContainer", false /* printLog */);
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
- if (!mWindowContextListenerController.assertCallerCanRemoveListener(clientToken,
+ if (!mWindowContextListenerController.assertCallerCanModifyListener(clientToken,
callerCanManageAppTokens, callingUid)) {
return;
}
@@ -3945,6 +3970,7 @@ public class WindowManagerService extends IWindowManager.Stub
return backgroundType == LETTERBOX_BACKGROUND_SOLID_COLOR
|| backgroundType == LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND
|| backgroundType == LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING
+ || backgroundType == LETTERBOX_BACKGROUND_WALLPAPER
? backgroundType : LETTERBOX_BACKGROUND_SOLID_COLOR;
}
@@ -3958,11 +3984,71 @@ public class WindowManagerService extends IWindowManager.Stub
return "LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND";
case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING:
return "LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING";
+ case LETTERBOX_BACKGROUND_WALLPAPER:
+ return "LETTERBOX_BACKGROUND_WALLPAPER";
default:
return "unknown=" + backgroundType;
}
}
+ /**
+ * Overrides alpha of a black scrim shown over wallpaper for {@link
+ * #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link mLetterboxBackgroundType}.
+ *
+ * <p>If given value is < 0 or >= 1, both it and a value of {@link
+ * com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha} are ignored
+ * and 0.0 (transparent) is instead.
+ */
+ void setLetterboxBackgroundWallpaperDarkScrimAlpha(float alpha) {
+ mLetterboxBackgroundWallpaperDarkScrimAlpha = alpha;
+ }
+
+ /**
+ * Resets alpha of a black scrim shown over wallpaper letterbox background to {@link
+ * com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha}.
+ */
+ void resetLetterboxBackgroundWallpaperDarkScrimAlpha() {
+ mLetterboxBackgroundWallpaperDarkScrimAlpha = mContext.getResources().getFloat(
+ com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha);
+ }
+
+ /**
+ * Gets alpha of a black scrim shown over wallpaper letterbox background.
+ */
+ float getLetterboxBackgroundWallpaperDarkScrimAlpha() {
+ return mLetterboxBackgroundWallpaperDarkScrimAlpha;
+ }
+
+ /**
+ * Overrides blur radius for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in
+ * {@link mLetterboxBackgroundType}.
+ *
+ * <p> If given value <= 0, both it and a value of {@link
+ * com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius} are ignored
+ * and 0 is used instead.
+ */
+ void setLetterboxBackgroundWallpaperBlurRadius(int radius) {
+ mLetterboxBackgroundWallpaperBlurRadius = radius;
+ }
+
+ /**
+ * Resets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link
+ * mLetterboxBackgroundType} to {@link
+ * com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius}.
+ */
+ void resetLetterboxBackgroundWallpaperBlurRadius() {
+ mLetterboxBackgroundWallpaperBlurRadius = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius);
+ }
+
+ /**
+ * Gets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link
+ * mLetterboxBackgroundType}.
+ */
+ int getLetterboxBackgroundWallpaperBlurRadius() {
+ return mLetterboxBackgroundWallpaperBlurRadius;
+ }
+
@Override
public void setIgnoreOrientationRequest(int displayId, boolean ignoreOrientationRequest) {
if (!checkCallingPermission(
@@ -5494,6 +5580,25 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ void setSandboxDisplayApis(int displayId, boolean sandboxDisplayApis) {
+ if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
+ }
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ if (displayContent != null) {
+ displayContent.setSandboxDisplayApis(sandboxDisplayApis);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
/** The global settings only apply to default display. */
private boolean applyForcedPropertiesForDefaultDisplay() {
boolean changed = false;
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 64a26ec69f03..5942f34048e7 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -22,6 +22,7 @@ import static android.view.CrossWindowBlurListeners.CROSS_WINDOW_BLUR_SUPPORTED;
import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_SOLID_COLOR;
+import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_WALLPAPER;
import android.graphics.Color;
import android.graphics.Point;
@@ -134,6 +135,16 @@ public class WindowManagerShellCommand extends ShellCommand {
return runSetLetterboxBackgroundColor(pw);
case "get-letterbox-background-color":
return runGetLetterboxBackgroundColor(pw);
+ case "set-letterbox-background-wallpaper-blur-radius":
+ return runSetLetterboxBackgroundWallpaperBlurRadius(pw);
+ case "get-letterbox-background-wallpaper-blur-radius":
+ return runGetLetterboxBackgroundWallpaperBlurRadius(pw);
+ case "set-letterbox-background-wallpaper-dark-scrim-alpha":
+ return runSetLetterboxBackgroundWallpaperDarkScrimAlpha(pw);
+ case "get-letterbox-background-wallpaper-dark-scrim-alpha":
+ return runGetLetterboxBackgroundWallpaperDarkScrimAlpha(pw);
+ case "set-sandbox-display-apis":
+ return runSandboxDisplayApis(pw);
case "reset":
return runReset(pw);
case "disable-blur":
@@ -344,6 +355,37 @@ public class WindowManagerShellCommand extends ShellCommand {
return 0;
}
+ /**
+ * Override display size and metrics to reflect the DisplayArea of the calling activity.
+ */
+ private int runSandboxDisplayApis(PrintWriter pw) throws RemoteException {
+ int displayId = Display.DEFAULT_DISPLAY;
+ String arg = getNextArgRequired();
+ if ("-d".equals(arg)) {
+ displayId = Integer.parseInt(getNextArgRequired());
+ arg = getNextArgRequired();
+ }
+
+ final boolean sandboxDisplayApis;
+ switch (arg) {
+ case "true":
+ case "1":
+ sandboxDisplayApis = true;
+ break;
+ case "false":
+ case "0":
+ sandboxDisplayApis = false;
+ break;
+ default:
+ getErrPrintWriter().println("Error: expecting true, 1, false, 0, but we "
+ + "get " + arg);
+ return -1;
+ }
+
+ mInternal.setSandboxDisplayApis(displayId, sandboxDisplayApis);
+ return 0;
+ }
+
private int runDismissKeyguard(PrintWriter pw) throws RemoteException {
mInterface.dismissKeyguard(null /* callback */, null /* message */);
return 0;
@@ -566,7 +608,9 @@ public class WindowManagerShellCommand extends ShellCommand {
try {
String arg = getNextArgRequired();
if ("reset".equals(arg)) {
- mInternal.resetFixedOrientationLetterboxAspectRatio();
+ synchronized (mInternal.mGlobalLock) {
+ mInternal.resetFixedOrientationLetterboxAspectRatio();
+ }
return 0;
}
aspectRatio = Float.parseFloat(arg);
@@ -578,17 +622,20 @@ public class WindowManagerShellCommand extends ShellCommand {
"Error: 'reset' or aspect ratio should be provided as an argument " + e);
return -1;
}
-
- mInternal.setFixedOrientationLetterboxAspectRatio(aspectRatio);
+ synchronized (mInternal.mGlobalLock) {
+ mInternal.setFixedOrientationLetterboxAspectRatio(aspectRatio);
+ }
return 0;
}
private int runGetFixedOrientationLetterboxAspectRatio(PrintWriter pw) throws RemoteException {
- final float aspectRatio = mInternal.getFixedOrientationLetterboxAspectRatio();
- if (aspectRatio <= WindowManagerService.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO) {
- pw.println("Letterbox aspect ratio is not set");
- } else {
- pw.println("Letterbox aspect ratio is " + aspectRatio);
+ synchronized (mInternal.mGlobalLock) {
+ final float aspectRatio = mInternal.getFixedOrientationLetterboxAspectRatio();
+ if (aspectRatio <= WindowManagerService.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO) {
+ pw.println("Letterbox aspect ratio is not set");
+ } else {
+ pw.println("Letterbox aspect ratio is " + aspectRatio);
+ }
}
return 0;
}
@@ -598,7 +645,9 @@ public class WindowManagerShellCommand extends ShellCommand {
try {
String arg = getNextArgRequired();
if ("reset".equals(arg)) {
- mInternal.resetLetterboxActivityCornersRadius();
+ synchronized (mInternal.mGlobalLock) {
+ mInternal.resetLetterboxActivityCornersRadius();
+ }
return 0;
}
cornersRadius = Integer.parseInt(arg);
@@ -610,17 +659,20 @@ public class WindowManagerShellCommand extends ShellCommand {
"Error: 'reset' or corners radius should be provided as an argument " + e);
return -1;
}
-
- mInternal.setLetterboxActivityCornersRadius(cornersRadius);
+ synchronized (mInternal.mGlobalLock) {
+ mInternal.setLetterboxActivityCornersRadius(cornersRadius);
+ }
return 0;
}
private int runGetLetterboxActivityCornersRadius(PrintWriter pw) throws RemoteException {
- final int cornersRadius = mInternal.getLetterboxActivityCornersRadius();
- if (cornersRadius < 0) {
- pw.println("Letterbox corners radius is not set");
- } else {
- pw.println("Letterbox corners radius is " + cornersRadius);
+ synchronized (mInternal.mGlobalLock) {
+ final int cornersRadius = mInternal.getLetterboxActivityCornersRadius();
+ if (cornersRadius < 0) {
+ pw.println("Letterbox corners radius is not set");
+ } else {
+ pw.println("Letterbox corners radius is " + cornersRadius);
+ }
}
return 0;
}
@@ -630,7 +682,9 @@ public class WindowManagerShellCommand extends ShellCommand {
String arg = getNextArgRequired();
if ("reset".equals(arg)) {
- mInternal.resetLetterboxBackgroundType();
+ synchronized (mInternal.mGlobalLock) {
+ mInternal.resetLetterboxBackgroundType();
+ }
return 0;
}
switch (arg) {
@@ -643,31 +697,42 @@ public class WindowManagerShellCommand extends ShellCommand {
case "app_color_background_floating":
backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
break;
+ case "wallpaper":
+ backgroundType = LETTERBOX_BACKGROUND_WALLPAPER;
+ break;
default:
getErrPrintWriter().println(
- "Error: 'reset', 'solid_color' or 'app_color_background' should "
- + "be provided as an argument");
+ "Error: 'reset', 'solid_color', 'app_color_background' or "
+ + "'wallpaper' should be provided as an argument");
return -1;
}
-
- mInternal.setLetterboxBackgroundType(backgroundType);
+ synchronized (mInternal.mGlobalLock) {
+ mInternal.setLetterboxBackgroundType(backgroundType);
+ }
return 0;
}
private int runGetLetterboxBackgroundType(PrintWriter pw) throws RemoteException {
- @LetterboxBackgroundType final int backgroundType = mInternal.getLetterboxBackgroundType();
- switch (backgroundType) {
- case LETTERBOX_BACKGROUND_SOLID_COLOR:
- pw.println("Letterbox background type is 'solid_color'");
- break;
- case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND:
- pw.println("Letterbox background type is 'app_color_background'");
- break;
- case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING:
- pw.println("Letterbox background type is 'app_color_background_floating'");
- break;
- default:
- throw new AssertionError("Unexpected letterbox background type: " + backgroundType);
+ synchronized (mInternal.mGlobalLock) {
+ @LetterboxBackgroundType final int backgroundType =
+ mInternal.getLetterboxBackgroundType();
+ switch (backgroundType) {
+ case LETTERBOX_BACKGROUND_SOLID_COLOR:
+ pw.println("Letterbox background type is 'solid_color'");
+ break;
+ case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND:
+ pw.println("Letterbox background type is 'app_color_background'");
+ break;
+ case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING:
+ pw.println("Letterbox background type is 'app_color_background_floating'");
+ break;
+ case LETTERBOX_BACKGROUND_WALLPAPER:
+ pw.println("Letterbox background type is 'wallpaper'");
+ break;
+ default:
+ throw new AssertionError(
+ "Unexpected letterbox background type: " + backgroundType);
+ }
}
return 0;
}
@@ -677,7 +742,9 @@ public class WindowManagerShellCommand extends ShellCommand {
String arg = getNextArgRequired();
try {
if ("reset".equals(arg)) {
- mInternal.resetLetterboxBackgroundColor();
+ synchronized (mInternal.mGlobalLock) {
+ mInternal.resetLetterboxBackgroundColor();
+ }
return 0;
}
color = Color.valueOf(Color.parseColor(arg));
@@ -687,14 +754,95 @@ public class WindowManagerShellCommand extends ShellCommand {
+ "an argument " + e + " but got " + arg);
return -1;
}
-
- mInternal.setLetterboxBackgroundColor(color);
+ synchronized (mInternal.mGlobalLock) {
+ mInternal.setLetterboxBackgroundColor(color);
+ }
return 0;
}
private int runGetLetterboxBackgroundColor(PrintWriter pw) throws RemoteException {
- final Color color = mInternal.getLetterboxBackgroundColor();
- pw.println("Letterbox background color is " + Integer.toHexString(color.toArgb()));
+ synchronized (mInternal.mGlobalLock) {
+ final Color color = mInternal.getLetterboxBackgroundColor();
+ pw.println("Letterbox background color is " + Integer.toHexString(color.toArgb()));
+ }
+ return 0;
+ }
+
+ private int runSetLetterboxBackgroundWallpaperBlurRadius(PrintWriter pw)
+ throws RemoteException {
+ final int radius;
+ try {
+ String arg = getNextArgRequired();
+ if ("reset".equals(arg)) {
+ synchronized (mInternal.mGlobalLock) {
+ mInternal.resetLetterboxBackgroundWallpaperBlurRadius();
+ }
+ return 0;
+ }
+ radius = Integer.parseInt(arg);
+ } catch (NumberFormatException e) {
+ getErrPrintWriter().println("Error: blur radius format " + e);
+ return -1;
+ } catch (IllegalArgumentException e) {
+ getErrPrintWriter().println(
+ "Error: 'reset' or blur radius should be provided as an argument " + e);
+ return -1;
+ }
+ synchronized (mInternal.mGlobalLock) {
+ mInternal.setLetterboxBackgroundWallpaperBlurRadius(radius);
+ }
+ return 0;
+ }
+
+ private int runGetLetterboxBackgroundWallpaperBlurRadius(PrintWriter pw)
+ throws RemoteException {
+ synchronized (mInternal.mGlobalLock) {
+ final int radius = mInternal.getLetterboxBackgroundWallpaperBlurRadius();
+ if (radius <= 0) {
+ pw.println("Letterbox background wallpaper blur radius is not set");
+ } else {
+ pw.println("Letterbox background wallpaper blur radius is " + radius);
+ }
+ }
+ return 0;
+ }
+
+ private int runSetLetterboxBackgroundWallpaperDarkScrimAlpha(PrintWriter pw)
+ throws RemoteException {
+ final float alpha;
+ try {
+ String arg = getNextArgRequired();
+ if ("reset".equals(arg)) {
+ synchronized (mInternal.mGlobalLock) {
+ mInternal.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
+ }
+ return 0;
+ }
+ alpha = Float.parseFloat(arg);
+ } catch (NumberFormatException e) {
+ getErrPrintWriter().println("Error: bad alpha format " + e);
+ return -1;
+ } catch (IllegalArgumentException e) {
+ getErrPrintWriter().println(
+ "Error: 'reset' or alpha should be provided as an argument " + e);
+ return -1;
+ }
+ synchronized (mInternal.mGlobalLock) {
+ mInternal.setLetterboxBackgroundWallpaperDarkScrimAlpha(alpha);
+ }
+ return 0;
+ }
+
+ private int runGetLetterboxBackgroundWallpaperDarkScrimAlpha(PrintWriter pw)
+ throws RemoteException {
+ synchronized (mInternal.mGlobalLock) {
+ final float alpha = mInternal.getLetterboxBackgroundWallpaperDarkScrimAlpha();
+ if (alpha < 0 || alpha >= 1) {
+ pw.println("Letterbox dark scrim alpha is not set");
+ } else {
+ pw.println("Letterbox dark scrim alpha is " + alpha);
+ }
+ }
return 0;
}
@@ -734,6 +882,15 @@ public class WindowManagerShellCommand extends ShellCommand {
// set-letterbox-background-color
mInternal.resetLetterboxBackgroundColor();
+ // set-letterbox-background-wallpaper-blur-radius
+ mInternal.resetLetterboxBackgroundWallpaperBlurRadius();
+
+ // set-letterbox-background-wallpaper-dark-scrim-alpha
+ mInternal.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
+
+ // set-sandbox-display-apis
+ mInternal.setSandboxDisplayApis(displayId, /* sandboxDisplayApis= */ true);
+
pw.println("Reset all settings for displayId=" + displayId);
return 0;
}
@@ -783,9 +940,24 @@ public class WindowManagerShellCommand extends ShellCommand {
pw.println(" and control letterbox background type. See Color#parseColor for allowed");
pw.println(" color formats (#RRGGBB and some colors by name, e.g. magenta or olive). ");
pw.println(" set-letterbox-background-type [reset|solid_color|app_color_background");
- pw.println(" |app_color_background_floating]");
+ pw.println(" |app_color_background_floating|wallpaper]");
pw.println(" get-letterbox-background-type");
pw.println(" Type of background used in the letterbox mode.");
+ pw.println(" set-letterbox-background-wallpaper-blur-radius [reset|radius]");
+ pw.println(" get-letterbox-background-wallpaper-blur-radius");
+ pw.println(" Blur radius for 'wallpaper' letterbox background. If radius <= 0");
+ pw.println(" both it and R.dimen.config_letterboxBackgroundWallpaperBlurRadius are ");
+ pw.println(" ignored and 0 is used.");
+ pw.println(" set-letterbox-background-wallpaper-dark-scrim-alpha [reset|alpha]");
+ pw.println(" get-letterbox-background-wallpaper-dark-scrim-alpha");
+ pw.println(" Alpha of a black translucent scrim shown over 'wallpaper'");
+ pw.println(" letterbox background. If alpha < 0 or >= 1 both it and");
+ pw.println(" R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha are ignored and ");
+ pw.println(" 0.0 (transparent) is used instead.");
+ pw.println(" set-sandbox-display-apis [true|1|false|0]");
+ pw.println(" Sets override of Display APIs getRealSize / getRealMetrics to reflect ");
+ pw.println(" DisplayArea of the activity, or the window bounds if in letterbox or");
+ pw.println(" Size Compat Mode.");
pw.println(" reset [-d DISPLAY_ID]");
pw.println(" Reset all override settings.");
if (!IS_USER) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 833f63747fd5..46d923b0cfb0 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -452,10 +452,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
/** The frames used to compute a temporal layout appearance. */
private WindowFrames mSimulatedWindowFrames;
- /**
- * Usually empty. Set to the task's tempInsetFrame. See
- *{@link android.app.IActivityTaskManager#resizePrimarySplitScreen}.
- */
+ /** Usually the same as {@link #getBounds()}. */
private final Rect mInsetFrame = new Rect();
/**
@@ -2919,21 +2916,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return processConfig;
}
- void getMergedConfiguration(MergedConfiguration outConfiguration) {
- final Configuration globalConfig = getProcessGlobalConfiguration();
- final Configuration overrideConfig = getMergedOverrideConfiguration();
- outConfiguration.setConfiguration(globalConfig, overrideConfig);
- }
-
- void setLastReportedMergedConfiguration(MergedConfiguration config) {
- mLastReportedConfiguration.setTo(config);
- mLastConfigReportedToClient = true;
- }
-
- void getLastReportedMergedConfiguration(MergedConfiguration config) {
- config.setTo(mLastReportedConfiguration);
- }
-
private Configuration getLastReportedConfiguration() {
return mLastReportedConfiguration.getMergedConfiguration();
}
@@ -3712,7 +3694,17 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return wpc != null && wpc.registeredForDisplayAreaConfigChanges();
}
- void fillClientWindowFrames(ClientWindowFrames outFrames) {
+ /**
+ * Fills the given window frames and merged configuration for the client.
+ *
+ * @param outFrames The frames that will be sent to the client.
+ * @param outMergedConfiguration The configuration that will be sent to the client.
+ * @param useLatestConfig Whether to use the latest configuration.
+ * @param relayoutVisible Whether to consider visibility to use the latest configuration.
+ */
+ void fillClientWindowFramesAndConfiguration(ClientWindowFrames outFrames,
+ MergedConfiguration outMergedConfiguration, boolean useLatestConfig,
+ boolean relayoutVisible) {
outFrames.frame.set(mWindowFrames.mCompatFrame);
outFrames.displayFrame.set(mWindowFrames.mDisplayFrame);
if (mInvGlobalScale != 1.0f && hasCompatScale()) {
@@ -3737,6 +3729,23 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
final DisplayInfo displayInfo = getDisplayInfo();
backdropFrame.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
}
+
+ // Note: in the cases where the window is tied to an activity, we should not send a
+ // configuration update when the window has requested to be hidden. Doing so can lead to
+ // the client erroneously accepting a configuration that would have otherwise caused an
+ // activity restart. We instead hand back the last reported {@link MergedConfiguration}.
+ if (useLatestConfig || (relayoutVisible && (shouldCheckTokenVisibleRequested()
+ || mToken.isVisibleRequested()))) {
+ final Configuration globalConfig = getProcessGlobalConfiguration();
+ final Configuration overrideConfig = getMergedOverrideConfiguration();
+ outMergedConfiguration.setConfiguration(globalConfig, overrideConfig);
+ if (outMergedConfiguration != mLastReportedConfiguration) {
+ mLastReportedConfiguration.setTo(outMergedConfiguration);
+ }
+ } else {
+ outMergedConfiguration.setTo(mLastReportedConfiguration);
+ }
+ mLastConfigReportedToClient = true;
}
void reportResized() {
@@ -3764,9 +3773,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
ProtoLog.i(WM_DEBUG_ORIENTATION, "Resizing %s WITH DRAW PENDING", this);
}
- getMergedConfiguration(mLastReportedConfiguration);
- mLastConfigReportedToClient = true;
-
final boolean reportOrientation = mReportOrientationChanged;
// Always reset these states first, so if {@link IWindow#resized} fails, this
// window won't be added to {@link WindowManagerService#mResizingWindows} and set
@@ -3776,18 +3782,20 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mDragResizingChangeReported = true;
mWindowFrames.clearReportResizeHints();
- final MergedConfiguration mergedConfiguration = mLastReportedConfiguration;
+ fillClientWindowFramesAndConfiguration(mClientWindowFrames, mLastReportedConfiguration,
+ true /* useLatestConfig */, false /* relayoutVisible */);
final boolean reportDraw = drawPending || useBLASTSync() || !mRedrawForSyncReported;
final boolean forceRelayout = reportOrientation || isDragResizeChanged() || !mRedrawForSyncReported;
- final int displayId = getDisplayId();
- fillClientWindowFrames(mClientWindowFrames);
+ final DisplayContent displayContent = getDisplayContent();
+ final boolean alwaysConsumeSystemBars =
+ displayContent.getDisplayPolicy().areSystemBarsForcedShownLw(this);
+ final int displayId = displayContent.getDisplayId();
markRedrawForSyncReported();
try {
- mClient.resized(mClientWindowFrames, reportDraw, mergedConfiguration, forceRelayout,
- getDisplayContent().getDisplayPolicy().areSystemBarsForcedShownLw(this),
- displayId);
+ mClient.resized(mClientWindowFrames, reportDraw, mLastReportedConfiguration,
+ forceRelayout, alwaysConsumeSystemBars, displayId);
if (drawPending && reportOrientation && mOrientationChanging) {
mOrientationChangeRedrawRequestTime = SystemClock.elapsedRealtime();
ProtoLog.v(WM_DEBUG_ORIENTATION,
@@ -4507,7 +4515,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
void requestUpdateWallpaperIfNeeded() {
final DisplayContent dc = getDisplayContent();
- if (dc != null && (mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
+ if (dc != null && hasWallpaper()) {
dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
dc.setLayoutNeeded();
mWmService.mWindowPlacerLocked.requestTraversal();
@@ -5867,7 +5875,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|| inMultiWindowMode()) {
return false;
}
- return (mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
+ return hasWallpaper();
+ }
+
+ boolean hasWallpaper() {
+ return (mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0
+ || (mActivityRecord != null && mActivityRecord.hasWallpaperBackgroudForLetterbox());
}
/**
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index d54cf5f17b4a..ef39560e59fc 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -16,7 +16,6 @@
package com.android.server.wm;
-import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
@@ -346,7 +345,7 @@ class WindowToken extends WindowContainer<WindowState> {
boolean windowsCanBeWallpaperTarget() {
for (int j = mChildren.size() - 1; j >= 0; j--) {
final WindowState w = mChildren.get(j);
- if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
+ if (w.hasWallpaper()) {
return true;
}
}
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 15f57653840b..a99679ade958 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -49,6 +49,7 @@ cc_library_static {
"com_android_server_net_NetworkStatsService.cpp",
"com_android_server_power_PowerManagerService.cpp",
"com_android_server_powerstats_PowerStatsService.cpp",
+ "com_android_server_hint_HintManagerService.cpp",
"com_android_server_SerialService.cpp",
"com_android_server_soundtrigger_middleware_AudioSessionProviderImpl.cpp",
"com_android_server_soundtrigger_middleware_ExternalCaptureStateTracker.cpp",
@@ -158,7 +159,7 @@ cc_defaults {
"android.hardware.memtrack-V1-ndk_platform",
"android.hardware.power@1.0",
"android.hardware.power@1.1",
- "android.hardware.power-V1-cpp",
+ "android.hardware.power-V2-cpp",
"android.hardware.power.stats@1.0",
"android.hardware.power.stats-V1-ndk_platform",
"android.hardware.thermal@1.0",
@@ -195,8 +196,8 @@ cc_defaults {
"libchrome",
"libmojo",
],
- }
- }
+ },
+ },
}
filegroup {
diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
index a4a74af8a1d9..e319e3febc21 100644
--- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
+++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
@@ -18,8 +18,11 @@
//#define LOG_NDEBUG 0
#include <android-base/file.h>
+#include <android-base/logging.h>
#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
#include <android_runtime/AndroidRuntime.h>
+#include <binder/IPCThreadState.h>
#include <cutils/compiler.h>
#include <dirent.h>
#include <jni.h>
@@ -27,9 +30,11 @@
#include <log/log.h>
#include <meminfo/procmeminfo.h>
#include <nativehelper/JNIHelp.h>
+#include <processgroup/processgroup.h>
#include <stddef.h>
#include <stdio.h>
#include <sys/mman.h>
+#include <sys/pidfd.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
@@ -37,29 +42,16 @@
#include <algorithm>
-#include <nativehelper/JNIHelp.h>
-#include <android_runtime/AndroidRuntime.h>
-#include <binder/IPCThreadState.h>
-#include <jni.h>
-#include <processgroup/processgroup.h>
-
using android::base::StringPrintf;
using android::base::WriteStringToFile;
using android::meminfo::ProcMemInfo;
using namespace android::meminfo;
-// This is temporarily hard-coded and should be removed once
-// bionic/libc/kernel/uapi/asm-generic/unistd.h are updated with process_madvise syscall header
-#ifndef __NR_process_madvise
-#define __NR_process_madvise 440
-#define MADV_COLD 20 /* deactivate these pages */
-#define MADV_PAGEOUT 21
-#endif
-
#define COMPACT_ACTION_FILE_FLAG 1
#define COMPACT_ACTION_ANON_FLAG 2
using VmaToAdviseFunc = std::function<int(const Vma&)>;
+using android::base::unique_fd;
#define SYNC_RECEIVED_WHILE_FROZEN (1)
#define ASYNC_RECEIVED_WHILE_FROZEN (2)
@@ -73,24 +65,25 @@ static inline void compactProcessProcfs(int pid, const std::string& compactionTy
WriteStringToFile(compactionType, reclaim_path);
}
-static int compactMemory(const std::vector<Vma>& vmas, int pid, int madviseType) {
+// Compacts a set of VMAs for pid using an madviseType accepted by process_madvise syscall
+// On success returns the total bytes that where compacted. On failure it returns
+// a negative error code from the standard linux error codes.
+static int64_t compactMemory(const std::vector<Vma>& vmas, int pid, int madviseType) {
// UIO_MAXIOV is currently a small value and we might have more addresses
// we do multiple syscalls if we exceed its maximum
static struct iovec vmasToKernel[UIO_MAXIOV];
- int err = 0;
-
if (vmas.empty()) {
- return err;
+ return 0;
}
- int pidfd = syscall(__NR_pidfd_open, pid, 0);
- err = -errno;
+ unique_fd pidfd(pidfd_open(pid, 0));
if (pidfd < 0) {
// Skip compaction if failed to open pidfd with any error
- return err;
+ return -errno;
}
+ int64_t totalBytesCompacted = 0;
for (int iBase = 0; iBase < vmas.size(); iBase += UIO_MAXIOV) {
int totalVmasToKernel = std::min(UIO_MAXIOV, (int)(vmas.size() - iBase));
for (int iVec = 0, iVma = iBase; iVec < totalVmasToKernel; ++iVec, ++iVma) {
@@ -98,17 +91,16 @@ static int compactMemory(const std::vector<Vma>& vmas, int pid, int madviseType)
vmasToKernel[iVec].iov_len = vmas[iVma].end - vmas[iVma].start;
}
- process_madvise(pidfd, vmasToKernel, totalVmasToKernel, madviseType, 0);
- err = -errno;
- if (CC_UNLIKELY(err == -ENOSYS)) {
- // Syscall does not exist, skip trying more calls process_madvise
- break;
+ auto bytesCompacted =
+ process_madvise(pidfd, vmasToKernel, totalVmasToKernel, madviseType, 0);
+ if (CC_UNLIKELY(bytesCompacted == -1)) {
+ return -errno;
}
- }
- close(pidfd);
+ totalBytesCompacted += bytesCompacted;
+ }
- return err;
+ return totalBytesCompacted;
}
static int getFilePageAdvice(const Vma& vma) {
@@ -132,7 +124,7 @@ static int getAnyPageAdvice(const Vma& vma) {
// Perform a full process compaction using process_madvise syscall
// reading all filtering VMAs and filtering pages as specified by pageFilter
-static int compactProcess(int pid, VmaToAdviseFunc vmaToAdviseFunc) {
+static int64_t compactProcess(int pid, VmaToAdviseFunc vmaToAdviseFunc) {
ProcMemInfo meminfo(pid);
std::vector<Vma> pageoutVmas, coldVmas;
auto vmaCollectorCb = [&coldVmas,&pageoutVmas,&vmaToAdviseFunc](const Vma& vma) {
@@ -148,11 +140,19 @@ static int compactProcess(int pid, VmaToAdviseFunc vmaToAdviseFunc) {
};
meminfo.ForEachVmaFromMaps(vmaCollectorCb);
- int err = compactMemory(pageoutVmas, pid, MADV_PAGEOUT);
- if (!err) {
- err = compactMemory(coldVmas, pid, MADV_COLD);
+ int64_t pageoutBytes = compactMemory(pageoutVmas, pid, MADV_PAGEOUT);
+ if (pageoutBytes < 0) {
+ // Error, just forward it.
+ return pageoutBytes;
}
- return err;
+
+ int64_t coldBytes = compactMemory(coldVmas, pid, MADV_COLD);
+ if (coldBytes < 0) {
+ // Error, just forward it.
+ return coldBytes;
+ }
+
+ return pageoutBytes + coldBytes;
}
// Compact process using process_madvise syscall or fallback to procfs in
diff --git a/services/core/jni/com_android_server_hint_HintManagerService.cpp b/services/core/jni/com_android_server_hint_HintManagerService.cpp
new file mode 100644
index 000000000000..000cb839002b
--- /dev/null
+++ b/services/core/jni/com_android_server_hint_HintManagerService.cpp
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ */
+
+#define TAG "HintManagerService-JNI"
+
+//#define LOG_NDEBUG 0
+
+#include <android-base/stringprintf.h>
+#include <android/hardware/power/IPower.h>
+#include <android_runtime/AndroidRuntime.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedPrimitiveArray.h>
+#include <powermanager/PowerHalController.h>
+#include <utils/Log.h>
+
+#include <unistd.h>
+#include <cinttypes>
+
+#include <sys/types.h>
+
+#include "jni.h"
+
+using android::hardware::power::IPowerHintSession;
+using android::hardware::power::WorkDuration;
+
+using android::base::StringPrintf;
+
+namespace android {
+
+static power::PowerHalController gPowerHalController;
+
+static jlong createHintSession(JNIEnv* env, int32_t tgid, int32_t uid,
+ std::vector<int32_t> threadIds, int64_t durationNanos) {
+ auto result =
+ gPowerHalController.createHintSession(tgid, uid, std::move(threadIds), durationNanos);
+ if (result.isOk()) {
+ sp<IPowerHintSession> appSession = result.value();
+ if (appSession) appSession->incStrong(env);
+ return reinterpret_cast<jlong>(appSession.get());
+ }
+ return 0;
+}
+
+static void pauseHintSession(JNIEnv* env, int64_t session_ptr) {
+ sp<IPowerHintSession> appSession = reinterpret_cast<IPowerHintSession*>(session_ptr);
+ appSession->pause();
+}
+
+static void resumeHintSession(JNIEnv* env, int64_t session_ptr) {
+ sp<IPowerHintSession> appSession = reinterpret_cast<IPowerHintSession*>(session_ptr);
+ appSession->resume();
+}
+
+static void closeHintSession(JNIEnv* env, int64_t session_ptr) {
+ sp<IPowerHintSession> appSession = reinterpret_cast<IPowerHintSession*>(session_ptr);
+ appSession->close();
+ appSession->decStrong(env);
+}
+
+static void updateTargetWorkDuration(int64_t session_ptr, int64_t targetDurationNanos) {
+ sp<IPowerHintSession> appSession = reinterpret_cast<IPowerHintSession*>(session_ptr);
+ appSession->updateTargetWorkDuration(targetDurationNanos);
+}
+
+static void reportActualWorkDuration(int64_t session_ptr,
+ const std::vector<WorkDuration>& actualDurations) {
+ sp<IPowerHintSession> appSession = reinterpret_cast<IPowerHintSession*>(session_ptr);
+ appSession->reportActualWorkDuration(actualDurations);
+}
+
+static int64_t getHintSessionPreferredRate() {
+ int64_t rate = -1;
+ auto result = gPowerHalController.getHintSessionPreferredRate();
+ if (result.isOk()) {
+ rate = result.value();
+ }
+ return rate;
+}
+
+// ----------------------------------------------------------------------------
+static void nativeInit(JNIEnv* env, jobject obj) {
+ gPowerHalController.init();
+}
+
+static jlong nativeCreateHintSession(JNIEnv* env, jclass /* clazz */, jint tgid, jint uid,
+ jintArray tids, jlong durationNanos) {
+ ScopedIntArrayRO tidArray(env, tids);
+ if (nullptr == tidArray.get() || tidArray.size() == 0) {
+ ALOGW("GetIntArrayElements returns nullptr.");
+ return 0;
+ }
+ std::vector<int32_t> threadIds(tidArray.size());
+ for (size_t i = 0; i < tidArray.size(); i++) {
+ threadIds[i] = tidArray[i];
+ }
+ return createHintSession(env, tgid, uid, std::move(threadIds), durationNanos);
+}
+
+static void nativePauseHintSession(JNIEnv* env, jclass /* clazz */, jlong session_ptr) {
+ pauseHintSession(env, session_ptr);
+}
+
+static void nativeResumeHintSession(JNIEnv* env, jclass /* clazz */, jlong session_ptr) {
+ resumeHintSession(env, session_ptr);
+}
+
+static void nativeCloseHintSession(JNIEnv* env, jclass /* clazz */, jlong session_ptr) {
+ closeHintSession(env, session_ptr);
+}
+
+static void nativeUpdateTargetWorkDuration(JNIEnv* /* env */, jclass /* clazz */, jlong session_ptr,
+ jlong targetDurationNanos) {
+ updateTargetWorkDuration(session_ptr, targetDurationNanos);
+}
+
+static void nativeReportActualWorkDuration(JNIEnv* env, jclass /* clazz */, jlong session_ptr,
+ jlongArray actualDurations, jlongArray timeStamps) {
+ ScopedLongArrayRO arrayActualDurations(env, actualDurations);
+ ScopedLongArrayRO arrayTimeStamps(env, timeStamps);
+
+ std::vector<WorkDuration> actualList(arrayActualDurations.size());
+ for (size_t i = 0; i < arrayActualDurations.size(); i++) {
+ actualList[i].timeStampNanos = arrayTimeStamps[i];
+ actualList[i].durationNanos = arrayActualDurations[i];
+ }
+ reportActualWorkDuration(session_ptr, actualList);
+}
+
+static jlong nativeGetHintSessionPreferredRate(JNIEnv* /* env */, jclass /* clazz */) {
+ return static_cast<jlong>(getHintSessionPreferredRate());
+}
+
+// ----------------------------------------------------------------------------
+static const JNINativeMethod sHintManagerServiceMethods[] = {
+ /* name, signature, funcPtr */
+ {"nativeInit", "()V", (void*)nativeInit},
+ {"nativeCreateHintSession", "(II[IJ)J", (void*)nativeCreateHintSession},
+ {"nativePauseHintSession", "(J)V", (void*)nativePauseHintSession},
+ {"nativeResumeHintSession", "(J)V", (void*)nativeResumeHintSession},
+ {"nativeCloseHintSession", "(J)V", (void*)nativeCloseHintSession},
+ {"nativeUpdateTargetWorkDuration", "(JJ)V", (void*)nativeUpdateTargetWorkDuration},
+ {"nativeReportActualWorkDuration", "(J[J[J)V", (void*)nativeReportActualWorkDuration},
+ {"nativeGetHintSessionPreferredRate", "()J", (void*)nativeGetHintSessionPreferredRate},
+};
+
+int register_android_server_HintManagerService(JNIEnv* env) {
+ return jniRegisterNativeMethods(env,
+ "com/android/server/power/hint/"
+ "HintManagerService$NativeWrapper",
+ sHintManagerServiceMethods, NELEM(sHintManagerServiceMethods));
+}
+
+} /* namespace android */
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index 9b7e27d891c4..ae7ea3cd90e8 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -100,7 +100,7 @@ static bool setPowerMode(Mode mode, bool enabled) {
ALOGD("Excessive delay in setting interactive mode to %s while turning screen %s",
enabled ? "true" : "false", enabled ? "on" : "off");
}
- return result == power::HalResult::SUCCESSFUL;
+ return result.isOk();
}
void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType,
diff --git a/services/core/jni/com_android_server_vibrator_VibratorController.cpp b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
index cf64a6847b46..b7fa7960ea99 100644
--- a/services/core/jni/com_android_server_vibrator_VibratorController.cpp
+++ b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
@@ -199,7 +199,7 @@ static jboolean vibratorIsAvailable(JNIEnv* env, jclass /* clazz */, jlong ptr)
ALOGE("vibratorIsAvailable failed because native wrapper was not initialized");
return JNI_FALSE;
}
- auto pingFn = [](std::shared_ptr<vibrator::HalWrapper> hal) { return hal->ping(); };
+ auto pingFn = [](vibrator::HalWrapper* hal) { return hal->ping(); };
return wrapper->halCall<void>(pingFn, "ping").isOk() ? JNI_TRUE : JNI_FALSE;
}
@@ -211,7 +211,7 @@ static jlong vibratorOn(JNIEnv* env, jclass /* clazz */, jlong ptr, jlong timeou
return -1;
}
auto callback = wrapper->createCallback(vibrationId);
- auto onFn = [&](std::shared_ptr<vibrator::HalWrapper> hal) {
+ auto onFn = [timeoutMs, &callback](vibrator::HalWrapper* hal) {
return hal->on(std::chrono::milliseconds(timeoutMs), callback);
};
auto result = wrapper->halCall<void>(onFn, "on");
@@ -224,7 +224,7 @@ static void vibratorOff(JNIEnv* env, jclass /* clazz */, jlong ptr) {
ALOGE("vibratorOff failed because native wrapper was not initialized");
return;
}
- auto offFn = [](std::shared_ptr<vibrator::HalWrapper> hal) { return hal->off(); };
+ auto offFn = [](vibrator::HalWrapper* hal) { return hal->off(); };
wrapper->halCall<void>(offFn, "off");
}
@@ -234,7 +234,7 @@ static void vibratorSetAmplitude(JNIEnv* env, jclass /* clazz */, jlong ptr, jfl
ALOGE("vibratorSetAmplitude failed because native wrapper was not initialized");
return;
}
- auto setAmplitudeFn = [&](std::shared_ptr<vibrator::HalWrapper> hal) {
+ auto setAmplitudeFn = [amplitude](vibrator::HalWrapper* hal) {
return hal->setAmplitude(static_cast<float>(amplitude));
};
wrapper->halCall<void>(setAmplitudeFn, "setAmplitude");
@@ -247,7 +247,7 @@ static void vibratorSetExternalControl(JNIEnv* env, jclass /* clazz */, jlong pt
ALOGE("vibratorSetExternalControl failed because native wrapper was not initialized");
return;
}
- auto setExternalControlFn = [&](std::shared_ptr<vibrator::HalWrapper> hal) {
+ auto setExternalControlFn = [enabled](vibrator::HalWrapper* hal) {
return hal->setExternalControl(enabled);
};
wrapper->halCall<void>(setExternalControlFn, "setExternalControl");
@@ -263,7 +263,7 @@ static jlong vibratorPerformEffect(JNIEnv* env, jclass /* clazz */, jlong ptr, j
aidl::Effect effectType = static_cast<aidl::Effect>(effect);
aidl::EffectStrength effectStrength = static_cast<aidl::EffectStrength>(strength);
auto callback = wrapper->createCallback(vibrationId);
- auto performEffectFn = [&](std::shared_ptr<vibrator::HalWrapper> hal) {
+ auto performEffectFn = [effectType, effectStrength, &callback](vibrator::HalWrapper* hal) {
return hal->performEffect(effectType, effectStrength, callback);
};
auto result = wrapper->halCall<std::chrono::milliseconds>(performEffectFn, "performEffect");
@@ -284,7 +284,7 @@ static jlong vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jlon
effects.push_back(effectFromJavaPrimitive(env, element));
}
auto callback = wrapper->createCallback(vibrationId);
- auto performComposedEffectFn = [&](std::shared_ptr<vibrator::HalWrapper> hal) {
+ auto performComposedEffectFn = [&effects, &callback](vibrator::HalWrapper* hal) {
return hal->performComposedEffect(effects, callback);
};
auto result = wrapper->halCall<std::chrono::milliseconds>(performComposedEffectFn,
@@ -319,7 +319,7 @@ static jlong vibratorPerformPwleEffect(JNIEnv* env, jclass /* clazz */, jlong pt
}
auto callback = wrapper->createCallback(vibrationId);
- auto performPwleEffectFn = [&](std::shared_ptr<vibrator::HalWrapper> hal) {
+ auto performPwleEffectFn = [&primitives, &callback](vibrator::HalWrapper* hal) {
return hal->performPwleEffect(primitives, callback);
};
auto result = wrapper->halCall<void>(performPwleEffectFn, "performPwleEffect");
@@ -333,7 +333,7 @@ static void vibratorAlwaysOnEnable(JNIEnv* env, jclass /* clazz */, jlong ptr, j
ALOGE("vibratorAlwaysOnEnable failed because native wrapper was not initialized");
return;
}
- auto alwaysOnEnableFn = [&](std::shared_ptr<vibrator::HalWrapper> hal) {
+ auto alwaysOnEnableFn = [id, effect, strength](vibrator::HalWrapper* hal) {
return hal->alwaysOnEnable(static_cast<int32_t>(id), static_cast<aidl::Effect>(effect),
static_cast<aidl::EffectStrength>(strength));
};
@@ -346,7 +346,7 @@ static void vibratorAlwaysOnDisable(JNIEnv* env, jclass /* clazz */, jlong ptr,
ALOGE("vibratorAlwaysOnDisable failed because native wrapper was not initialized");
return;
}
- auto alwaysOnDisableFn = [&](std::shared_ptr<vibrator::HalWrapper> hal) {
+ auto alwaysOnDisableFn = [id](vibrator::HalWrapper* hal) {
return hal->alwaysOnDisable(static_cast<int32_t>(id));
};
wrapper->halCall<void>(alwaysOnDisableFn, "alwaysOnDisable");
@@ -446,11 +446,11 @@ int register_android_server_vibrator_VibratorController(JavaVM* jvm, JNIEnv* env
sRampClassInfo.duration = GetFieldIDOrDie(env, rampClass, "mDuration", "I");
jclass frequencyMappingClass = FindClassOrDie(env, "android/os/VibratorInfo$FrequencyMapping");
- sFrequencyMappingClass = (jclass)env->NewGlobalRef(frequencyMappingClass);
+ sFrequencyMappingClass = static_cast<jclass>(env->NewGlobalRef(frequencyMappingClass));
sFrequencyMappingCtor = GetMethodIDOrDie(env, sFrequencyMappingClass, "<init>", "(FFFF[F)V");
jclass vibratorInfoClass = FindClassOrDie(env, "android/os/VibratorInfo");
- sVibratorInfoClass = (jclass)env->NewGlobalRef(vibratorInfoClass);
+ sVibratorInfoClass = static_cast<jclass>(env->NewGlobalRef(vibratorInfoClass));
sVibratorInfoCtor = GetMethodIDOrDie(env, sVibratorInfoClass, "<init>",
"(IJ[I[I[IFLandroid/os/VibratorInfo$FrequencyMapping;)V");
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 03a01523b8e2..f257686cbf3d 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -30,6 +30,7 @@ int register_android_server_InputManager(JNIEnv* env);
int register_android_server_LightsService(JNIEnv* env);
int register_android_server_PowerManagerService(JNIEnv* env);
int register_android_server_PowerStatsService(JNIEnv* env);
+int register_android_server_HintManagerService(JNIEnv* env);
int register_android_server_storage_AppFuse(JNIEnv* env);
int register_android_server_SerialService(JNIEnv* env);
int register_android_server_SystemServer(JNIEnv* env);
@@ -79,6 +80,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_android_server_broadcastradio_Tuner(vm, env);
register_android_server_PowerManagerService(env);
register_android_server_PowerStatsService(env);
+ register_android_server_HintManagerService(env);
register_android_server_SerialService(env);
register_android_server_InputManager(env);
register_android_server_LightsService(env);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
index fb0265ed0b3a..ff7514a377e5 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
@@ -144,13 +144,13 @@ class ActiveAdmin {
private static final String TAG_ENROLLMENT_SPECIFIC_ID = "enrollment-specific-id";
private static final String TAG_ADMIN_CAN_GRANT_SENSORS_PERMISSIONS =
"admin-can-grant-sensors-permissions";
- private static final String TAG_ENTERPRISE_NETWORK_PREFERENCE_ENABLED =
- "enterprise-network-preference-enabled";
+ private static final String TAG_PREFERENTIAL_NETWORK_SERVICE_ENABLED =
+ "preferential-network-service-enabled";
private static final String TAG_USB_DATA_SIGNALING = "usb-data-signaling";
private static final String ATTR_VALUE = "value";
private static final String ATTR_LAST_NETWORK_LOGGING_NOTIFICATION = "last-notification";
private static final String ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS = "num-notifications";
- private static final boolean ENTERPRISE_NETWORK_PREFERENCE_ENABLED_DEFAULT = true;
+ private static final boolean PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT = true;
DeviceAdminInfo info;
@@ -296,8 +296,8 @@ class ActiveAdmin {
public String mOrganizationId;
public String mEnrollmentSpecificId;
public boolean mAdminCanGrantSensorsPermissions;
- public boolean mEnterpriseNetworkPreferenceEnabled =
- ENTERPRISE_NETWORK_PREFERENCE_ENABLED_DEFAULT;
+ public boolean mPreferentialNetworkServiceEnabled =
+ PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT;
private static final boolean USB_DATA_SIGNALING_ENABLED_DEFAULT = true;
boolean mUsbDataSignalingEnabled = USB_DATA_SIGNALING_ENABLED_DEFAULT;
@@ -576,9 +576,9 @@ class ActiveAdmin {
}
writeAttributeValueToXml(out, TAG_ADMIN_CAN_GRANT_SENSORS_PERMISSIONS,
mAdminCanGrantSensorsPermissions);
- if (mEnterpriseNetworkPreferenceEnabled != ENTERPRISE_NETWORK_PREFERENCE_ENABLED_DEFAULT) {
- writeAttributeValueToXml(out, TAG_ENTERPRISE_NETWORK_PREFERENCE_ENABLED,
- mEnterpriseNetworkPreferenceEnabled);
+ if (mPreferentialNetworkServiceEnabled != PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT) {
+ writeAttributeValueToXml(out, TAG_PREFERENTIAL_NETWORK_SERVICE_ENABLED,
+ mPreferentialNetworkServiceEnabled);
}
if (mUsbDataSignalingEnabled != USB_DATA_SIGNALING_ENABLED_DEFAULT) {
writeAttributeValueToXml(out, TAG_USB_DATA_SIGNALING, mUsbDataSignalingEnabled);
@@ -806,9 +806,9 @@ class ActiveAdmin {
mAlwaysOnVpnPackage = parser.getAttributeValue(null, ATTR_VALUE);
} else if (TAG_ALWAYS_ON_VPN_LOCKDOWN.equals(tag)) {
mAlwaysOnVpnLockdown = parser.getAttributeBoolean(null, ATTR_VALUE, false);
- } else if (TAG_ENTERPRISE_NETWORK_PREFERENCE_ENABLED.equals(tag)) {
- mEnterpriseNetworkPreferenceEnabled = parser.getAttributeBoolean(
- null, ATTR_VALUE, ENTERPRISE_NETWORK_PREFERENCE_ENABLED_DEFAULT);
+ } else if (TAG_PREFERENTIAL_NETWORK_SERVICE_ENABLED.equals(tag)) {
+ mPreferentialNetworkServiceEnabled = parser.getAttributeBoolean(
+ null, ATTR_VALUE, PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT);
} else if (TAG_COMMON_CRITERIA_MODE.equals(tag)) {
mCommonCriteriaMode = parser.getAttributeBoolean(null, ATTR_VALUE, false);
} else if (TAG_PASSWORD_COMPLEXITY.equals(tag)) {
@@ -1168,8 +1168,8 @@ class ActiveAdmin {
pw.print("mAlwaysOnVpnLockdown=");
pw.println(mAlwaysOnVpnLockdown);
- pw.print("mEnterpriseNetworkPreferenceEnabled=");
- pw.println(mEnterpriseNetworkPreferenceEnabled);
+ pw.print("mPreferentialNetworkServiceEnabled=");
+ pw.println(mPreferentialNetworkServiceEnabled);
pw.print("mCommonCriteriaMode=");
pw.println(mCommonCriteriaMode);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 20a88af98300..1ba57fd0251b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -3123,13 +3123,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
updatePermissionPolicyCache(userId);
updateAdminCanGrantSensorsPermissionCache(userId);
- boolean enableEnterpriseNetworkPreferenceEnabled = true;
+ boolean preferentialNetworkServiceEnabled = true;
synchronized (getLockObject()) {
ActiveAdmin owner = getDeviceOrProfileOwnerAdminLocked(userId);
- enableEnterpriseNetworkPreferenceEnabled = owner != null
- ? owner.mEnterpriseNetworkPreferenceEnabled : true;
+ preferentialNetworkServiceEnabled = owner != null
+ ? owner.mPreferentialNetworkServiceEnabled : true;
}
- updateNetworkPreferenceForUser(userId, enableEnterpriseNetworkPreferenceEnabled);
+ updateNetworkPreferenceForUser(userId, preferentialNetworkServiceEnabled);
startOwnerService(userId, "start-user");
}
@@ -11616,32 +11616,32 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
@Override
- public void setEnterpriseNetworkPreferenceEnabled(boolean enabled) {
+ public void setPreferentialNetworkServiceEnabled(boolean enabled) {
if (!mHasFeature) {
return;
}
final CallerIdentity caller = getCallerIdentity();
Preconditions.checkCallAuthorization(isProfileOwner(caller),
"Caller is not profile owner;"
- + " only profile owner may control the enterprise network preference");
+ + " only profile owner may control the preferntial network service");
synchronized (getLockObject()) {
final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(
caller.getUserId());
if (requiredAdmin != null
- && requiredAdmin.mEnterpriseNetworkPreferenceEnabled != enabled) {
- requiredAdmin.mEnterpriseNetworkPreferenceEnabled = enabled;
+ && requiredAdmin.mPreferentialNetworkServiceEnabled != enabled) {
+ requiredAdmin.mPreferentialNetworkServiceEnabled = enabled;
saveSettingsLocked(caller.getUserId());
}
}
updateNetworkPreferenceForUser(caller.getUserId(), enabled);
DevicePolicyEventLogger
- .createEvent(DevicePolicyEnums.SET_ENTERPRISE_NETWORK_PREFERENCE_ENABLED)
+ .createEvent(DevicePolicyEnums.SET_PREFERENTIAL_NETWORK_SERVICE_ENABLED)
.setBoolean(enabled)
.write();
}
@Override
- public boolean isEnterpriseNetworkPreferenceEnabled(int userHandle) {
+ public boolean isPreferentialNetworkServiceEnabled(int userHandle) {
if (!mHasFeature) {
return false;
}
@@ -11652,7 +11652,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
synchronized (getLockObject()) {
final ActiveAdmin requiredAdmin = getProfileOwnerAdminLocked(userHandle);
if (requiredAdmin != null) {
- return requiredAdmin.mEnterpriseNetworkPreferenceEnabled;
+ return requiredAdmin.mPreferentialNetworkServiceEnabled;
} else {
return false;
}
@@ -11698,9 +11698,18 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public boolean isLockTaskPermitted(String pkg) {
- final int userHandle = mInjector.userHandleGetCallingUserId();
+ // Check policy-exempt apps first, as it doesn't require the lock
+ if (listPolicyExemptAppsUnchecked().contains(pkg)) {
+ if (VERBOSE_LOG) {
+ Slogf.v(LOG_TAG, "isLockTaskPermitted(%s): returning true for policy-exempt app",
+ pkg);
+ }
+ return true;
+ }
+
+ final int userId = mInjector.userHandleGetCallingUserId();
synchronized (getLockObject()) {
- return getUserData(userHandle).mLockTaskPackages.contains(pkg);
+ return getUserData(userId).mLockTaskPackages.contains(pkg);
}
}
@@ -17227,11 +17236,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
private void updateNetworkPreferenceForUser(int userId,
- boolean enableEnterpriseNetworkPreferenceEnabled) {
+ boolean preferentialNetworkServiceEnabled) {
if (!isManagedProfile(userId)) {
return;
}
- int networkPreference = enableEnterpriseNetworkPreferenceEnabled
+ int networkPreference = preferentialNetworkServiceEnabled
? PROFILE_NETWORK_PREFERENCE_ENTERPRISE : PROFILE_NETWORK_PREFERENCE_DEFAULT;
mInjector.binderWithCleanCallingIdentity(() ->
mInjector.getConnectivityManager().setProfileNetworkPreference(
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 1426579a0f64..912b8cad952c 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -170,6 +170,7 @@ import com.android.server.policy.role.RoleServicePlatformHelperImpl;
import com.android.server.power.PowerManagerService;
import com.android.server.power.ShutdownThread;
import com.android.server.power.ThermalManagerService;
+import com.android.server.power.hint.HintManagerService;
import com.android.server.powerstats.PowerStatsService;
import com.android.server.profcollect.ProfcollectForwardingService;
import com.android.server.recoverysystem.RecoverySystemService;
@@ -1074,6 +1075,10 @@ public final class SystemServer implements Dumpable {
mSystemServiceManager.startService(ThermalManagerService.class);
t.traceEnd();
+ t.traceBegin("StartHintManager");
+ mSystemServiceManager.startService(HintManagerService.class);
+ t.traceEnd();
+
// Now that the power manager has been started, let the activity manager
// initialize power management features.
t.traceBegin("InitPowerManagement");
@@ -2503,10 +2508,12 @@ public final class SystemServer implements Dumpable {
}
// Translation manager service
- if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TRANSLATION)) {
+ if (deviceHasConfigString(context, R.string.config_defaultTranslationService)) {
t.traceBegin("StartTranslationManagerService");
mSystemServiceManager.startService(TRANSLATION_MANAGER_SERVICE_CLASS);
t.traceEnd();
+ } else {
+ Slog.d(TAG, "TranslationService not defined by OEM");
}
// NOTE: ClipboardService depends on ContentCapture and Autofill
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ActiveServicesTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ActiveServicesTest.java
deleted file mode 100644
index 0633ab92acf8..000000000000
--- a/services/tests/mockingservicestests/src/com/android/server/am/ActiveServicesTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.am;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
-import static com.android.server.am.ActiveServices.FGS_BG_START_USE_EXEMPTION_LIST_CHANGE_ID;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-
-import android.app.compat.CompatChanges;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoSession;
-import org.mockito.quality.Strictness;
-
-
-
-@RunWith(AndroidJUnit4.class)
-public class ActiveServicesTest {
-
- private MockitoSession mMockingSession;
-
- @Before
- public void setUp() {
- mMockingSession = mockitoSession()
- .initMocks(this)
- .strictness(Strictness.LENIENT)
- .mockStatic(CompatChanges.class)
- .startMocking();
- }
-
- @After
- public void tearDown() {
- if (mMockingSession != null) {
- mMockingSession.finishMocking();
- }
- }
-
- private void checkPackageExempted(String pkg, int uid, boolean expected) {
- assertEquals("Package=" + pkg + " uid=" + uid,
- expected, ActiveServices.isPackageExemptedFromFgsRestriction(pkg, uid));
- }
-
- @Test
- public void isPackageExemptedFromFgsRestriction() {
- // Compat changes are enabled by default.
- when(CompatChanges.isChangeEnabled(anyLong(), anyInt())).thenReturn(true);
-
- checkPackageExempted("", 1, false);
- checkPackageExempted("abc", 1, false);
- checkPackageExempted("com.random", 1, false);
-
- // This package is exempted but not its subpackages.
- checkPackageExempted("com.google.pixel.exo.bootstrapping", 1, true);
- checkPackageExempted("com.google.pixel.exo.bootstrapping.subpackage", 1, false);
-
- // Subpackages are also exempted.
- checkPackageExempted("com.android.webview", 1, true);
- checkPackageExempted("com.android.webview.beta", 1, true);
- checkPackageExempted("com.chrome", 1, true);
- checkPackageExempted("com.chrome.canary", 1, true);
-
- checkPackageExempted("com.android.webviewx", 1, false);
-
- // Now toggle the compat ID for a specific UID.
- when(CompatChanges.isChangeEnabled(FGS_BG_START_USE_EXEMPTION_LIST_CHANGE_ID, 10))
- .thenReturn(false);
- // Exempted package, but compat id is disabled for the UID.
- checkPackageExempted("com.android.webview", 10, false);
-
- // Exempted package, but compat id is still enabled for the UID.
- checkPackageExempted("com.android.webview", 11, true);
- }
-}
diff --git a/services/tests/mockingservicestests/src/com/android/server/power/FaceDownDetectorTest.java b/services/tests/mockingservicestests/src/com/android/server/power/FaceDownDetectorTest.java
index 8ecb07158564..e093f1396385 100644
--- a/services/tests/mockingservicestests/src/com/android/server/power/FaceDownDetectorTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/power/FaceDownDetectorTest.java
@@ -24,6 +24,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
+import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorManager;
@@ -129,10 +130,7 @@ public class FaceDownDetectorTest {
triggerFaceDown();
// Phone flips
- for (int i = 0; i < 10; i++) {
- advanceTime(Duration.ofMillis(5));
- mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 1.0f, 0.0f));
- }
+ triggerUnflip();
assertThat(mOnFaceDownCalls).isEqualTo(1);
assertThat(mOnFaceDownExitCalls).isEqualTo(1);
@@ -184,6 +182,47 @@ public class FaceDownDetectorTest {
assertThat(mOnFaceDownCalls).isEqualTo(1);
}
+ @Test
+ public void faceDownToScreenOff_followedByScreenOnAndUserInteraction_doesNotDisable()
+ throws Exception {
+ mFaceDownDetector.systemReady(sContext);
+ // Face down to screen off
+ triggerFaceDown();
+ mFaceDownDetector.mScreenReceiver.onReceive(sContext, new Intent(Intent.ACTION_SCREEN_OFF));
+
+ // Screen on
+ mFaceDownDetector.mScreenReceiver.onReceive(sContext, new Intent(Intent.ACTION_SCREEN_ON));
+
+ // User interaction
+ mFaceDownDetector.userActivity(PowerManager.USER_ACTIVITY_EVENT_TOUCH);
+ waitForListenerToHandle();
+
+ // Attempt another face down to see if disabled
+ triggerFaceDown();
+
+ assertThat(mOnFaceDownCalls).isEqualTo(2);
+ }
+
+ @Test
+ public void faceDownUserInteraction_disablesDetector() throws Exception {
+ mFaceDownDetector.systemReady(sContext);
+ triggerFaceDown();
+ mFaceDownDetector.userActivity(PowerManager.USER_ACTIVITY_EVENT_TOUCH);
+ waitForListenerToHandle();
+
+ triggerUnflip();
+ triggerFaceDown();
+
+ assertThat(mOnFaceDownCalls).isEqualTo(1);
+ }
+
+ private void triggerUnflip() throws Exception {
+ for (int i = 0; i < 10; i++) {
+ advanceTime(Duration.ofMillis(5));
+ mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 1.0f, 0.0f));
+ }
+ }
+
private void triggerFaceDown() throws Exception {
// Face up
// Using 0.5 on x to simulate constant acceleration, such as a sloped surface.
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java b/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java
index 7afcbf7ead1c..5de8a7abc90a 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import android.annotation.NonNull;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.PackageManager;
@@ -38,6 +39,11 @@ import com.android.server.appsearch.external.localstorage.stats.CallStats;
import org.junit.Before;
import org.junit.Test;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
public class PlatformLoggerTest {
private static final int TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS = 100;
private static final int TEST_DEFAULT_SAMPLING_RATIO = 10;
@@ -57,15 +63,23 @@ public class PlatformLoggerTest {
};
}
+ static int calculateHashCodeMd5withBigInteger(@NonNull String str) throws
+ NoSuchAlgorithmException, UnsupportedEncodingException {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ md.update(str.getBytes(/*charsetName=*/ "UTF-8"));
+ byte[] digest = md.digest();
+ return new BigInteger(digest).intValue();
+ }
+
@Test
- public void testcreateExtraStatsLocked_nullSamplingRatioMap_returnsDefaultSamplingRatio() {
+ public void testCreateExtraStatsLocked_nullSamplingRatioMap_returnsDefaultSamplingRatio() {
PlatformLogger logger = new PlatformLogger(
ApplicationProvider.getApplicationContext(),
UserHandle.USER_NULL,
new PlatformLogger.Config(
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
TEST_DEFAULT_SAMPLING_RATIO,
- /*samplingRatioMap=*/ null));
+ /*samplingRatios=*/ new SparseIntArray()));
// Make sure default sampling ratio is used if samplingMap is not provided.
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
@@ -84,7 +98,7 @@ public class PlatformLoggerTest {
@Test
- public void testcreateExtraStatsLocked_with_samplingRatioMap_returnsConfiguredSamplingRatio() {
+ public void testCreateExtraStatsLocked_with_samplingRatioMap_returnsConfiguredSamplingRatio() {
int putDocumentSamplingRatio = 1;
int querySamplingRatio = 2;
final SparseIntArray samplingRatios = new SparseIntArray();
@@ -98,8 +112,8 @@ public class PlatformLoggerTest {
TEST_DEFAULT_SAMPLING_RATIO,
samplingRatios));
- // The default sampling ratio should be used if no sampling ratio is
- // provided for certain call type.
+ // The default sampling ratio should be used if no sampling ratio is
+ // provided for certain call type.
assertThat(logger.createExtraStatsLocked(TEST_PACKAGE_NAME,
CallStats.CALL_TYPE_INITIALIZE).mSamplingRatio).isEqualTo(
TEST_DEFAULT_SAMPLING_RATIO);
@@ -118,6 +132,70 @@ public class PlatformLoggerTest {
}
@Test
+ public void testCalculateHashCode_MD5_int32_shortString()
+ throws NoSuchAlgorithmException, UnsupportedEncodingException {
+ final String str1 = "d1";
+ final String str2 = "d2";
+
+ int hashCodeForStr1 = PlatformLogger.calculateHashCodeMd5(str1);
+
+ // hashing should be stable
+ assertThat(hashCodeForStr1).isEqualTo(
+ PlatformLogger.calculateHashCodeMd5(str1));
+ assertThat(hashCodeForStr1).isNotEqualTo(
+ PlatformLogger.calculateHashCodeMd5(str2));
+ }
+
+ @Test
+ public void testGetCalculateCode_MD5_int32_mediumString()
+ throws NoSuchAlgorithmException, UnsupportedEncodingException {
+ final String str1 = "Siblings";
+ final String str2 = "Teheran";
+
+ int hashCodeForStr1 = PlatformLogger.calculateHashCodeMd5(str1);
+
+ // hashing should be stable
+ assertThat(hashCodeForStr1).isEqualTo(
+ PlatformLogger.calculateHashCodeMd5(str1));
+ assertThat(hashCodeForStr1).isNotEqualTo(
+ PlatformLogger.calculateHashCodeMd5(str2));
+ }
+
+ @Test
+ public void testCalculateHashCode_MD5_int32_longString() throws NoSuchAlgorithmException,
+ UnsupportedEncodingException {
+ final String str1 = "abcdefghijkl-mnopqrstuvwxyz";
+ final String str2 = "abcdefghijkl-mnopqrstuvwxy123";
+
+ int hashCodeForStr1 = PlatformLogger.calculateHashCodeMd5(str1);
+
+ // hashing should be stable
+ assertThat(hashCodeForStr1).isEqualTo(
+ PlatformLogger.calculateHashCodeMd5(str1));
+ assertThat(hashCodeForStr1).isNotEqualTo(
+ PlatformLogger.calculateHashCodeMd5(str2));
+ }
+
+ @Test
+ public void testCalculateHashCode_MD5_int32_sameAsBigInteger_intValue() throws
+ NoSuchAlgorithmException, UnsupportedEncodingException {
+ final String emptyStr = "";
+ final String shortStr = "a";
+ final String mediumStr = "Teheran";
+ final String longStr = "abcd-efgh-ijkl-mnop-qrst-uvwx-yz";
+
+ int emptyHashCode = PlatformLogger.calculateHashCodeMd5(emptyStr);
+ int shortHashCode = PlatformLogger.calculateHashCodeMd5(shortStr);
+ int mediumHashCode = PlatformLogger.calculateHashCodeMd5(mediumStr);
+ int longHashCode = PlatformLogger.calculateHashCodeMd5(longStr);
+
+ assertThat(emptyHashCode).isEqualTo(calculateHashCodeMd5withBigInteger(emptyStr));
+ assertThat(shortHashCode).isEqualTo(calculateHashCodeMd5withBigInteger(shortStr));
+ assertThat(mediumHashCode).isEqualTo(calculateHashCodeMd5withBigInteger(mediumStr));
+ assertThat(longHashCode).isEqualTo(calculateHashCodeMd5withBigInteger(longStr));
+ }
+
+ @Test
public void testShouldLogForTypeLocked_trueWhenSampleRatioIsOne() {
final int samplingRatio = 1;
final String testPackageName = "packageName";
@@ -127,7 +205,7 @@ public class PlatformLoggerTest {
new PlatformLogger.Config(
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
samplingRatio,
- /* samplingMap=*/ null));
+ /*samplingRatios=*/ new SparseIntArray()));
// Sample should always be logged for the first time if sampling is disabled(value is one).
assertThat(logger.shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)).isTrue();
@@ -145,7 +223,7 @@ public class PlatformLoggerTest {
new PlatformLogger.Config(
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
samplingRatio,
- /* samplingMap=*/ null));
+ /*samplingRatios=*/ new SparseIntArray()));
// Makes sure sample will be excluded due to sampling if sample ratio is negative.
assertThat(logger.shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)).isFalse();
@@ -167,7 +245,7 @@ public class PlatformLoggerTest {
new PlatformLogger.Config(
minTimeIntervalBetweenSamplesMillis,
samplingRatio,
- /* samplingMap=*/ null));
+ /*samplingRatios=*/ new SparseIntArray()));
logger.setLastPushTimeMillisLocked(SystemClock.elapsedRealtime());
// Makes sure sample will be excluded due to rate limiting if samples are too close.
@@ -189,7 +267,7 @@ public class PlatformLoggerTest {
new PlatformLogger.Config(
minTimeIntervalBetweenSamplesMillis,
samplingRatio,
- /* samplingMap=*/ null));
+ /*samplingRatios=*/ new SparseIntArray()));
logger.setLastPushTimeMillisLocked(SystemClock.elapsedRealtime());
// Makes sure sample will be logged if it is not too close to previous sample.
@@ -209,7 +287,7 @@ public class PlatformLoggerTest {
new PlatformLogger.Config(
TEST_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS,
TEST_DEFAULT_SAMPLING_RATIO,
- /* samplingMap=*/ null));
+ /*samplingRatios=*/ new SparseIntArray()));
mMockPackageManager.mockGetPackageUidAsUser(testPackageName, mContext.getUserId(), testUid);
//
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
index 3cbc22654292..e322ce551372 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
@@ -279,7 +279,7 @@ public class AuthSessionTest {
IBiometricAuthenticator fingerprintAuthenticator = mock(IBiometricAuthenticator.class);
when(fingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
when(fingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
- mSensors.add(new BiometricSensor(id,
+ mSensors.add(new BiometricSensor(mContext, id,
TYPE_FINGERPRINT /* modality */,
Authenticators.BIOMETRIC_STRONG /* strength */,
fingerprintAuthenticator) {
@@ -314,7 +314,7 @@ public class AuthSessionTest {
IBiometricAuthenticator authenticator) throws RemoteException {
when(authenticator.isHardwareDetected(any())).thenReturn(true);
when(authenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
- mSensors.add(new BiometricSensor(id,
+ mSensors.add(new BiometricSensor(mContext, id,
TYPE_FACE /* modality */,
Authenticators.BIOMETRIC_STRONG /* strength */,
authenticator) {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index abc873766de1..a5fbab519aaa 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -1278,10 +1278,10 @@ public class BiometricServiceTest {
for (int i = 0; i < testCases.length; i++) {
final BiometricSensor sensor =
- new BiometricSensor(0 /* id */,
+ new BiometricSensor(mContext, 0 /* id */,
BiometricAuthenticator.TYPE_FINGERPRINT,
testCases[i][0],
- null /* impl */) {
+ mock(IBiometricAuthenticator.class)) {
@Override
boolean confirmationAlwaysRequired(int userId) {
return false;
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java
index bb2b1c2fb0db..ee5ab92065ee 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java
@@ -24,6 +24,7 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.annotation.NonNull;
import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricManager.Authenticators;
@@ -35,7 +36,10 @@ import androidx.test.filters.SmallTest;
import com.android.server.biometrics.BiometricService.InvalidationTracker;
+import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
@@ -43,29 +47,37 @@ import java.util.ArrayList;
@SmallTest
public class InvalidationTrackerTest {
+ @Mock
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ }
+
@Test
public void testCallbackReceived_whenAllStrongSensorsInvalidated() throws Exception {
final IBiometricAuthenticator authenticator1 = mock(IBiometricAuthenticator.class);
when(authenticator1.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
- final TestSensor sensor1 = new TestSensor(0 /* id */,
+ final TestSensor sensor1 = new TestSensor(mContext, 0 /* id */,
BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
authenticator1);
final IBiometricAuthenticator authenticator2 = mock(IBiometricAuthenticator.class);
when(authenticator2.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
- final TestSensor sensor2 = new TestSensor(1 /* id */,
+ final TestSensor sensor2 = new TestSensor(mContext, 1 /* id */,
BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
authenticator2);
final IBiometricAuthenticator authenticator3 = mock(IBiometricAuthenticator.class);
when(authenticator3.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
- final TestSensor sensor3 = new TestSensor(2 /* id */,
+ final TestSensor sensor3 = new TestSensor(mContext, 2 /* id */,
BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG,
authenticator3);
final IBiometricAuthenticator authenticator4 = mock(IBiometricAuthenticator.class);
when(authenticator4.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
- final TestSensor sensor4 = new TestSensor(3 /* id */,
+ final TestSensor sensor4 = new TestSensor(mContext, 3 /* id */,
BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_WEAK,
authenticator4);
@@ -101,8 +113,9 @@ public class InvalidationTrackerTest {
private static class TestSensor extends BiometricSensor {
- TestSensor(int id, int modality, int strength, IBiometricAuthenticator impl) {
- super(id, modality, strength, impl);
+ TestSensor(@NonNull Context context, int id, int modality, int strength,
+ @NonNull IBiometricAuthenticator impl) {
+ super(context, id, modality, strength, impl);
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
index 7dd073499c73..c5ed20afacec 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
@@ -188,7 +188,7 @@ public class BiometricSchedulerTest {
// Request it to be canceled. The operation can be canceled immediately, and the scheduler
// should go back to idle, since in this case the framework has not even requested the HAL
// to authenticate yet.
- mScheduler.cancelAuthentication(mToken);
+ mScheduler.cancelAuthenticationOrDetection(mToken);
assertNull(mScheduler.mCurrentOperation);
}
@@ -298,7 +298,7 @@ public class BiometricSchedulerTest {
mScheduler.mPendingOperations.getFirst().mState);
// Request cancel before the authentication client has started
- mScheduler.cancelAuthentication(mToken);
+ mScheduler.cancelAuthenticationOrDetection(mToken);
waitForIdle();
assertEquals(Operation.STATE_WAITING_IN_QUEUE_CANCELING,
mScheduler.mPendingOperations.getFirst().mState);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 486d2b35f9f3..78e2dee7acf8 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -4032,20 +4032,20 @@ public class DevicePolicyManagerTest extends DpmTestBase {
}
@Test
- public void testGetSetEnterpriseNetworkPreference() throws Exception {
+ public void testGetSetPreferentialNetworkService() throws Exception {
assertExpectException(SecurityException.class, null,
- () -> dpm.setEnterpriseNetworkPreferenceEnabled(false));
+ () -> dpm.setPreferentialNetworkServiceEnabled(false));
assertExpectException(SecurityException.class, null,
- () -> dpm.isEnterpriseNetworkPreferenceEnabled());
+ () -> dpm.isPreferentialNetworkServiceEnabled());
final int managedProfileUserId = 15;
final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
addManagedProfile(admin1, managedProfileAdminUid, admin1);
mContext.binder.callingUid = managedProfileAdminUid;
- dpm.setEnterpriseNetworkPreferenceEnabled(false);
- assertThat(dpm.isEnterpriseNetworkPreferenceEnabled()).isFalse();
+ dpm.setPreferentialNetworkServiceEnabled(false);
+ assertThat(dpm.isPreferentialNetworkServiceEnabled()).isFalse();
verify(getServices().connectivityManager, times(1)).setProfileNetworkPreference(
eq(UserHandle.of(managedProfileUserId)),
eq(ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT),
@@ -4053,8 +4053,8 @@ public class DevicePolicyManagerTest extends DpmTestBase {
any()
);
- dpm.setEnterpriseNetworkPreferenceEnabled(true);
- assertThat(dpm.isEnterpriseNetworkPreferenceEnabled()).isTrue();
+ dpm.setPreferentialNetworkServiceEnabled(true);
+ assertThat(dpm.isPreferentialNetworkServiceEnabled()).isTrue();
verify(getServices().connectivityManager, times(1)).setProfileNetworkPreference(
eq(UserHandle.of(managedProfileUserId)),
eq(ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE),
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
index c8099e2467a1..cda659f05adf 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
@@ -27,10 +27,13 @@ import static com.android.server.display.DisplayModeDirector.Vote.PRIORITY_FLICK
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -45,6 +48,7 @@ import android.hardware.Sensor;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.display.DisplayManager;
+import android.hardware.fingerprint.IUdfpsHbmListener;
import android.os.Handler;
import android.os.Looper;
import android.provider.DeviceConfig;
@@ -61,9 +65,11 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.Preconditions;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.internal.util.test.FakeSettingsProviderRule;
+import com.android.server.LocalServices;
import com.android.server.display.DisplayModeDirector.BrightnessObserver;
import com.android.server.display.DisplayModeDirector.DesiredDisplayModeSpecs;
import com.android.server.display.DisplayModeDirector.Vote;
+import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.testutils.FakeDeviceConfigInterface;
import org.junit.Before;
@@ -71,6 +77,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
@@ -95,6 +102,8 @@ public class DisplayModeDirectorTest {
private Handler mHandler;
@Rule
public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
+ @Mock
+ public StatusBarManagerInternal mStatusBarMock;
@Before
public void setUp() throws Exception {
@@ -104,6 +113,9 @@ public class DisplayModeDirectorTest {
when(mContext.getContentResolver()).thenReturn(resolver);
mInjector = new FakesInjector();
mHandler = new Handler(Looper.getMainLooper());
+
+ LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
+ LocalServices.addService(StatusBarManagerInternal.class, mStatusBarMock);
}
private DisplayModeDirector createDirectorFromRefreshRateArray(
@@ -338,7 +350,7 @@ public class DisplayModeDirectorTest {
void verifyBrightnessObserverCall(DisplayModeDirector director, float minFps, float peakFps,
float defaultFps, float brightnessObserverMin, float brightnessObserverMax) {
- BrightnessObserver brightnessObserver = Mockito.mock(BrightnessObserver.class);
+ BrightnessObserver brightnessObserver = mock(BrightnessObserver.class);
director.injectBrightnessObserver(brightnessObserver);
director.getDesiredDisplayModeSpecsWithInjectedFpsSettings(minFps, peakFps, defaultFps);
verify(brightnessObserver)
@@ -581,7 +593,7 @@ public class DisplayModeDirectorTest {
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 20 /*lux*/));
Vote vote = director.getVote(Display.DEFAULT_DISPLAY, PRIORITY_FLICKER);
- assertVoteForRefreshRateLocked(vote, 90 /*fps*/);
+ assertVoteForRefreshRate(vote, 90 /*fps*/);
setBrightness(125);
// Sensor reads 1000 lux,
@@ -611,7 +623,7 @@ public class DisplayModeDirectorTest {
ArgumentCaptor<SensorEventListener> listenerCaptor =
ArgumentCaptor.forClass(SensorEventListener.class);
- Mockito.verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1)))
+ verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1)))
.registerListener(
listenerCaptor.capture(),
eq(lightSensor),
@@ -631,7 +643,7 @@ public class DisplayModeDirectorTest {
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 9000));
vote = director.getVote(Display.DEFAULT_DISPLAY, PRIORITY_FLICKER);
- assertVoteForRefreshRateLocked(vote, 60 /*fps*/);
+ assertVoteForRefreshRate(vote, 60 /*fps*/);
}
@Test
@@ -654,21 +666,21 @@ public class DisplayModeDirectorTest {
director.start(sensorManager);
ArgumentCaptor<SensorEventListener> listenerCaptor =
ArgumentCaptor.forClass(SensorEventListener.class);
- Mockito.verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1)))
+ verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1)))
.registerListener(
listenerCaptor.capture(),
eq(lightSensor),
anyInt(),
any(Handler.class));
- // Dispaly state changed from On to Doze
+ // Display state changed from On to Doze
director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_DOZE);
- Mockito.verify(sensorManager)
+ verify(sensorManager)
.unregisterListener(listenerCaptor.capture());
- // Dispaly state changed from Doze to On
+ // Display state changed from Doze to On
director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
- Mockito.verify(sensorManager, times(2))
+ verify(sensorManager, times(2))
.registerListener(
listenerCaptor.capture(),
eq(lightSensor),
@@ -677,7 +689,42 @@ public class DisplayModeDirectorTest {
}
- private void assertVoteForRefreshRateLocked(Vote vote, float refreshRate) {
+ @Test
+ public void testUdfpsListenerGetsRegistered() {
+ DisplayModeDirector director =
+ createDirectorFromRefreshRateArray(new float[] {60.f, 90.f, 110.f}, 0);
+ verify(mStatusBarMock, never()).setUdfpsHbmListener(any());
+
+ director.start(createMockSensorManager());
+ verify(mStatusBarMock).setUdfpsHbmListener(eq(director.getUdpfsObserver()));
+ }
+
+ @Test
+ public void testGbhmVotesFor60hz() throws Exception {
+ DisplayModeDirector director =
+ createDirectorFromRefreshRateArray(new float[] {60.f, 90.f, 110.f}, 0);
+ director.start(createMockSensorManager());
+ ArgumentCaptor<IUdfpsHbmListener> captor =
+ ArgumentCaptor.forClass(IUdfpsHbmListener.class);
+ verify(mStatusBarMock).setUdfpsHbmListener(captor.capture());
+ IUdfpsHbmListener hbmListener = captor.getValue();
+
+ // Should be no vote initially
+ Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
+ assertNull(vote);
+
+ // Enabling GHBM votes for 60hz
+ hbmListener.onHbmEnabled(IUdfpsHbmListener.GLOBAL_HBM, DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
+ assertVoteForRefreshRate(vote, 60.f);
+
+ // Disabling GHBM removes the vote
+ hbmListener.onHbmDisabled(IUdfpsHbmListener.GLOBAL_HBM, DISPLAY_ID);
+ vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
+ assertNull(vote);
+ }
+
+ private void assertVoteForRefreshRate(Vote vote, float refreshRate) {
assertThat(vote).isNotNull();
final DisplayModeDirector.RefreshRateRange expectedRange =
new DisplayModeDirector.RefreshRateRange(refreshRate, refreshRate);
@@ -787,7 +834,7 @@ public class DisplayModeDirectorTest {
}
private static SensorManager createMockSensorManager(Sensor... sensors) {
- SensorManager sensorManager = Mockito.mock(SensorManager.class);
+ SensorManager sensorManager = mock(SensorManager.class);
when(sensorManager.getSensorList(anyInt())).then((invocation) -> {
List<Sensor> requestedSensors = new ArrayList<>();
int type = invocation.getArgument(0);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java b/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java
index 375704ee31bf..e2b6a99bb978 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java
@@ -65,7 +65,7 @@ final class FakeHdmiCecConfig extends HdmiCecConfig {
R.bool.config_cecHdmiCecVersion20_default);
doReturn(true).when(resources).getBoolean(
- R.bool.config_cecSendStandbyOnSleep_userConfigurable);
+ R.bool.config_cecPowerControlMode_userConfigurable);
doReturn(true).when(resources).getBoolean(
R.bool.config_cecPowerControlModeTv_allowed);
doReturn(true).when(resources).getBoolean(
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
index c834510ba24c..a37f94b023fd 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
@@ -403,7 +403,7 @@ public final class HdmiCecConfigTest {
@Test
public void setStringValue_NotConfigurable() {
- setBooleanResource(R.bool.config_cecSendStandbyOnSleep_userConfigurable, false);
+ setBooleanResource(R.bool.config_cecPowerControlMode_userConfigurable, false);
HdmiCecConfig hdmiCecConfig = new HdmiCecConfig(mContext, mStorageAdapter);
assertThrows(IllegalArgumentException.class,
() -> hdmiCecConfig.setStringValue(
diff --git a/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java b/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java
index 401d6e30df13..2f771260ac1b 100644
--- a/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java
@@ -39,6 +39,8 @@ import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.InetAddress;
+import java.util.ArrayList;
import java.util.Arrays;
/**
@@ -53,8 +55,8 @@ public class IpConfigStoreTest {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
DataOutputStream outputStream = new DataOutputStream(byteStream);
- IpConfiguration expectedConfig = new IpConfiguration(IpAssignment.DHCP,
- ProxySettings.NONE, null, null);
+ final IpConfiguration expectedConfig =
+ newIpConfiguration(IpAssignment.DHCP, ProxySettings.NONE, null, null);
// Emulate writing to old format.
writeDhcpConfigV2(outputStream, KEY_CONFIG, expectedConfig);
@@ -78,18 +80,23 @@ public class IpConfigStoreTest {
final String DNS_IP_ADDR_1 = "1.2.3.4";
final String DNS_IP_ADDR_2 = "5.6.7.8";
- StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
- staticIpConfiguration.ipAddress = new LinkAddress(IP_ADDR_1);
- staticIpConfiguration.dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_1));
- staticIpConfiguration.dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_2));
+ final ArrayList<InetAddress> dnsServers = new ArrayList<>();
+ dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_1));
+ dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_2));
+ final StaticIpConfiguration staticIpConfiguration1 = new StaticIpConfiguration.Builder()
+ .setIpAddress(new LinkAddress(IP_ADDR_1))
+ .setDnsServers(dnsServers).build();
+ final StaticIpConfiguration staticIpConfiguration2 = new StaticIpConfiguration.Builder()
+ .setIpAddress(new LinkAddress(IP_ADDR_2))
+ .setDnsServers(dnsServers).build();
ProxyInfo proxyInfo =
ProxyInfo.buildDirectProxy("10.10.10.10", 88, Arrays.asList("host1", "host2"));
- IpConfiguration expectedConfig1 = new IpConfiguration(IpAssignment.STATIC,
- ProxySettings.STATIC, staticIpConfiguration, proxyInfo);
- IpConfiguration expectedConfig2 = new IpConfiguration(expectedConfig1);
- expectedConfig2.getStaticIpConfiguration().ipAddress = new LinkAddress(IP_ADDR_2);
+ IpConfiguration expectedConfig1 = newIpConfiguration(IpAssignment.STATIC,
+ ProxySettings.STATIC, staticIpConfiguration1, proxyInfo);
+ IpConfiguration expectedConfig2 = newIpConfiguration(IpAssignment.STATIC,
+ ProxySettings.STATIC, staticIpConfiguration2, proxyInfo);
ArrayMap<String, IpConfiguration> expectedNetworks = new ArrayMap<>();
expectedNetworks.put(IFACE_1, expectedConfig1);
@@ -107,14 +114,24 @@ public class IpConfigStoreTest {
assertEquals(expectedNetworks.get(IFACE_2), actualNetworks.get(IFACE_2));
}
+ private IpConfiguration newIpConfiguration(IpAssignment ipAssignment,
+ ProxySettings proxySettings, StaticIpConfiguration staticIpConfig, ProxyInfo info) {
+ final IpConfiguration config = new IpConfiguration();
+ config.setIpAssignment(ipAssignment);
+ config.setProxySettings(proxySettings);
+ config.setStaticIpConfiguration(staticIpConfig);
+ config.setHttpProxy(info);
+ return config;
+ }
+
// This is simplified snapshot of code that was used to store values in V2 format (key as int).
private static void writeDhcpConfigV2(DataOutputStream out, int configKey,
IpConfiguration config) throws IOException {
out.writeInt(2); // VERSION 2
- switch (config.ipAssignment) {
+ switch (config.getIpAssignment()) {
case DHCP:
out.writeUTF("ipAssignment");
- out.writeUTF(config.ipAssignment.toString());
+ out.writeUTF(config.getIpAssignment().toString());
break;
default:
fail("Not supported in test environment");
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index e9e24866f35c..352832b34c96 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -87,6 +87,7 @@ import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
@@ -226,7 +227,8 @@ public class NetworkPolicyManagerServiceTest {
private static final String TEST_SSID = "AndroidAP";
private static final String TEST_IMSI = "310210";
private static final int TEST_SUB_ID = 42;
- private static final int TEST_NET_ID = 24;
+ private static final Network TEST_NETWORK = mock(Network.class, CALLS_REAL_METHODS);
+
private static NetworkTemplate sTemplateWifi = buildTemplateWifi(TEST_SSID);
private static NetworkTemplate sTemplateMobileAll = buildTemplateMobileAll(TEST_IMSI);
@@ -1637,7 +1639,7 @@ public class NetworkPolicyManagerServiceTest {
@Test
public void testOpportunisticQuota() throws Exception {
- final Network net = new Network(TEST_NET_ID);
+ final Network net = TEST_NETWORK;
final NetworkPolicyManagerInternal internal = LocalServices
.getService(NetworkPolicyManagerInternal.class);
@@ -1759,11 +1761,10 @@ public class NetworkPolicyManagerServiceTest {
assertNotNull(callback);
expectNetworkStateSnapshot(true /* roaming */);
callback.onCapabilitiesChanged(
- new Network(TEST_NET_ID),
- buildNetworkCapabilities(TEST_SUB_ID, true /* roaming */));
+ TEST_NETWORK, buildNetworkCapabilities(TEST_SUB_ID, true /* roaming */));
assertEquals(0, internal.getSubscriptionOpportunisticQuota(
- new Network(TEST_NET_ID), NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH));
+ TEST_NETWORK, NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH));
}
}
@@ -2013,14 +2014,14 @@ public class NetworkPolicyManagerServiceTest {
}
private NetworkCapabilities buildNetworkCapabilities(int subId, boolean roaming) {
- final NetworkCapabilities nc = new NetworkCapabilities();
- nc.addTransportType(TRANSPORT_CELLULAR);
+ final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
+ builder.addTransportType(TRANSPORT_CELLULAR);
if (!roaming) {
- nc.addCapability(NET_CAPABILITY_NOT_ROAMING);
+ builder.addCapability(NET_CAPABILITY_NOT_ROAMING);
}
- nc.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
+ builder.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
.setSubscriptionId(subId).build());
- return nc;
+ return builder.build();
}
private NetworkPolicy buildDefaultFakeMobilePolicy() {
@@ -2061,10 +2062,9 @@ public class NetworkPolicyManagerServiceTest {
private static NetworkStateSnapshot buildWifi() {
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(TEST_IFACE);
- final NetworkCapabilities networkCapabilities = new NetworkCapabilities();
- networkCapabilities.addTransportType(TRANSPORT_WIFI);
- networkCapabilities.setSSID(TEST_SSID);
- return new NetworkStateSnapshot(new Network(TEST_NET_ID), networkCapabilities, prop,
+ final NetworkCapabilities networkCapabilities = new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_WIFI).setSsid(TEST_SSID).build();
+ return new NetworkStateSnapshot(TEST_NETWORK, networkCapabilities, prop,
null /*subscriberId*/, TYPE_WIFI);
}
@@ -2086,7 +2086,7 @@ public class NetworkPolicyManagerServiceTest {
when(mCarrierConfigManager.getConfigForSubId(eq(TEST_SUB_ID)))
.thenReturn(mCarrierConfig);
List<NetworkStateSnapshot> snapshots = List.of(new NetworkStateSnapshot(
- new Network(TEST_NET_ID),
+ TEST_NETWORK,
buildNetworkCapabilities(TEST_SUB_ID, roaming),
buildLinkProperties(TEST_IFACE), TEST_IMSI, TYPE_MOBILE));
when(mConnManager.getAllNetworkStateSnapshot()).thenReturn(snapshots);
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 589b3b403e6c..198fb4f5d295 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -691,7 +691,8 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
@Override
public void putDocuments(String packageName, String databaseName,
- List<Bundle> documentBundles, int userId, IAppSearchBatchResultCallback callback)
+ List<Bundle> documentBundles, int userId, long binderCallStartTimeMillis,
+ IAppSearchBatchResultCallback callback)
throws RemoteException {
final List<GenericDocument> docs = new ArrayList<>(documentBundles.size());
for (Bundle bundle : documentBundles) {
@@ -2041,6 +2042,11 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
return mService.getPackageShortcutForTest(packageName, shortcutId, userId);
}
+ protected void updatePackageShortcut(String packageName, String shortcutId, int userId,
+ Consumer<ShortcutInfo> cb) {
+ mService.updatePackageShortcutForTest(packageName, shortcutId, userId, cb);
+ }
+
protected void assertShortcutExists(String packageName, String shortcutId, int userId) {
assertTrue(getPackageShortcut(packageName, shortcutId, userId) != null);
}
@@ -2236,6 +2242,10 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
return getPackageShortcut(getCallingPackage(), shortcutId, getCallingUserId());
}
+ protected void updateCallerShortcut(String shortcutId, Consumer<ShortcutInfo> cb) {
+ updatePackageShortcut(getCallingPackage(), shortcutId, getCallingUserId(), cb);
+ }
+
protected List<ShortcutInfo> getLauncherShortcuts(String launcher, int userId, int queryFlags) {
final List<ShortcutInfo>[] ret = new List[1];
runWithCaller(launcher, userId, () -> {
@@ -2395,6 +2405,8 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
deleteAllSavedFiles();
+ mMockAppSearchManager.removeShortcuts();
+
initService();
mService.applyRestore(payload, USER_0);
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 4d0beef99cca..c16e49899dc2 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -1702,8 +1702,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Because setDynamicShortcuts will update the timestamps when ranks are changing,
// we explicitly set timestamps here.
- getCallerShortcut("s1").setTimestamp(5000);
- getCallerShortcut("s2").setTimestamp(1000);
+ updateCallerShortcut("s1", si -> si.setTimestamp(5000));
+ updateCallerShortcut("s2", si -> si.setTimestamp(1000));
setCaller(CALLING_PACKAGE_2);
final ShortcutInfo s2_2 = makeShortcut("s2");
@@ -1713,9 +1713,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
makeComponent(ShortcutActivity.class));
assertTrue(mManager.setDynamicShortcuts(list(s2_2, s2_3, s2_4)));
- getCallerShortcut("s2").setTimestamp(1500);
- getCallerShortcut("s3").setTimestamp(3000);
- getCallerShortcut("s4").setTimestamp(500);
+ updateCallerShortcut("s2", si -> si.setTimestamp(1500));
+ updateCallerShortcut("s3", si -> si.setTimestamp(3000));
+ updateCallerShortcut("s4", si -> si.setTimestamp(500));
setCaller(CALLING_PACKAGE_3);
final ShortcutInfo s3_2 = makeShortcutWithLocusId("s3", makeLocusId("l2"));
@@ -1723,7 +1723,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertTrue(mManager.setDynamicShortcuts(list(s3_2)));
- getCallerShortcut("s3").setTimestamp(START_TIME + 5000);
+ updateCallerShortcut("s3", si -> si.setTimestamp(START_TIME + 5000));
setCaller(LAUNCHER_1);
@@ -7686,7 +7686,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals("http://www/", si.getIntent().getData().toString());
assertEquals("foo/bar", si.getIntent().getType());
assertEquals(
- new ComponentName("abc", ".xyz"), si.getIntent().getComponent());
+ new ComponentName("abc", "abc.xyz"), si.getIntent().getComponent());
assertEquals(set("cat1", "cat2"), si.getIntent().getCategories());
assertEquals("value1", si.getIntent().getStringExtra("key1"));
diff --git a/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java
new file mode 100644
index 000000000000..aaf40d7e4461
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java
@@ -0,0 +1,268 @@
+/*
+ * 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.power.hint;
+
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.IHintSession;
+import android.os.Process;
+
+import com.android.server.FgThread;
+import com.android.server.power.hint.HintManagerService.AppHintSession;
+import com.android.server.power.hint.HintManagerService.Injector;
+import com.android.server.power.hint.HintManagerService.NativeWrapper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for {@link com.android.server.power.hint.HintManagerService}.
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:HintManagerServiceTest
+ */
+public class HintManagerServiceTest {
+ private static final long DEFAULT_HINT_PREFERRED_RATE = 16666666L;
+ private static final long DEFAULT_TARGET_DURATION = 16666666L;
+ private static final int UID = Process.myUid();
+ private static final int TID = Process.myPid();
+ private static final int TGID = Process.getThreadGroupLeader(TID);
+ private static final int[] SESSION_TIDS_A = new int[] {TID};
+ private static final int[] SESSION_TIDS_B = new int[] {TID};
+ private static final long[] DURATIONS_THREE = new long[] {1L, 100L, 1000L};
+ private static final long[] TIMESTAMPS_THREE = new long[] {1L, 2L, 3L};
+ private static final long[] DURATIONS_ZERO = new long[] {};
+ private static final long[] TIMESTAMPS_ZERO = new long[] {};
+ private static final long[] TIMESTAMPS_TWO = new long[] {1L, 2L};
+
+ @Mock private Context mContext;
+ @Mock private HintManagerService.NativeWrapper mNativeWrapperMock;
+
+ private HintManagerService mService;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ when(mNativeWrapperMock.halGetHintSessionPreferredRate())
+ .thenReturn(DEFAULT_HINT_PREFERRED_RATE);
+ when(mNativeWrapperMock.halCreateHintSession(eq(TGID), eq(UID), eq(SESSION_TIDS_A),
+ eq(DEFAULT_TARGET_DURATION))).thenReturn(1L);
+ when(mNativeWrapperMock.halCreateHintSession(eq(TGID), eq(UID), eq(SESSION_TIDS_B),
+ eq(DEFAULT_TARGET_DURATION))).thenReturn(2L);
+ }
+
+ private HintManagerService createService() {
+ mService = new HintManagerService(mContext, new Injector() {
+ NativeWrapper createNativeWrapper() {
+ return mNativeWrapperMock;
+ }
+ });
+ return mService;
+ }
+
+ @Test
+ public void testInitializeService() {
+ HintManagerService service = createService();
+ verify(mNativeWrapperMock).halInit();
+ assertThat(service.mHintSessionPreferredRate).isEqualTo(DEFAULT_HINT_PREFERRED_RATE);
+ }
+
+ @Test
+ public void testCreateHintSession() throws Exception {
+ HintManagerService service = createService();
+ IBinder token = new Binder();
+
+ IHintSession a = service.getBinderServiceInstance().createHintSession(token,
+ SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
+ assertNotNull(a);
+
+ IHintSession b = service.getBinderServiceInstance().createHintSession(token,
+ SESSION_TIDS_B, DEFAULT_TARGET_DURATION);
+ assertNotEquals(a, b);
+ }
+
+ @Test
+ public void testPauseResumeHintSession() throws Exception {
+ HintManagerService service = createService();
+ IBinder token = new Binder();
+
+ AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
+ .createHintSession(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
+
+ // Set session to background and calling updateHintAllowed() would invoke pause();
+ service.mUidObserver.onUidStateChanged(
+ a.mUid, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0);
+ final Object sync = new Object();
+ FgThread.getHandler().post(() -> {
+ synchronized (sync) {
+ sync.notify();
+ }
+ });
+ synchronized (sync) {
+ sync.wait();
+ }
+ assumeFalse(a.updateHintAllowed());
+ verify(mNativeWrapperMock, times(1)).halPauseHintSession(anyLong());
+
+ // Set session to foreground and calling updateHintAllowed() would invoke resume();
+ service.mUidObserver.onUidStateChanged(
+ a.mUid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 0, 0);
+ FgThread.getHandler().post(() -> {
+ synchronized (sync) {
+ sync.notify();
+ }
+ });
+ synchronized (sync) {
+ sync.wait();
+ }
+ assumeTrue(a.updateHintAllowed());
+ verify(mNativeWrapperMock, times(1)).halResumeHintSession(anyLong());
+ }
+
+ @Test
+ public void testCloseHintSession() throws Exception {
+ HintManagerService service = createService();
+ IBinder token = new Binder();
+
+ IHintSession a = service.getBinderServiceInstance().createHintSession(token,
+ SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
+
+ a.close();
+ verify(mNativeWrapperMock, times(1)).halCloseHintSession(anyLong());
+ }
+
+ @Test
+ public void testUpdateTargetWorkDuration() throws Exception {
+ HintManagerService service = createService();
+ IBinder token = new Binder();
+
+ IHintSession a = service.getBinderServiceInstance().createHintSession(token,
+ SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
+
+ assertThrows(IllegalArgumentException.class, () -> {
+ a.updateTargetWorkDuration(-1L);
+ });
+
+ assertThrows(IllegalArgumentException.class, () -> {
+ a.updateTargetWorkDuration(0L);
+ });
+
+ a.updateTargetWorkDuration(100L);
+ verify(mNativeWrapperMock, times(1)).halUpdateTargetWorkDuration(anyLong(), eq(100L));
+ }
+
+ @Test
+ public void testReportActualWorkDuration() throws Exception {
+ HintManagerService service = createService();
+ IBinder token = new Binder();
+
+ AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
+ .createHintSession(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
+
+ a.updateTargetWorkDuration(100L);
+ a.reportActualWorkDuration(DURATIONS_THREE, TIMESTAMPS_THREE);
+ verify(mNativeWrapperMock, times(1)).halReportActualWorkDuration(anyLong(),
+ eq(DURATIONS_THREE), eq(TIMESTAMPS_THREE));
+
+ assertThrows(IllegalArgumentException.class, () -> {
+ a.reportActualWorkDuration(DURATIONS_ZERO, TIMESTAMPS_THREE);
+ });
+
+ assertThrows(IllegalArgumentException.class, () -> {
+ a.reportActualWorkDuration(DURATIONS_THREE, TIMESTAMPS_ZERO);
+ });
+
+ assertThrows(IllegalArgumentException.class, () -> {
+ a.reportActualWorkDuration(DURATIONS_THREE, TIMESTAMPS_TWO);
+ });
+
+ reset(mNativeWrapperMock);
+ // Set session to background, then the duration would not be updated.
+ service.mUidObserver.onUidStateChanged(
+ a.mUid, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0);
+ final Object sync = new Object();
+ FgThread.getHandler().post(() -> {
+ synchronized (sync) {
+ sync.notify();
+ }
+ });
+ synchronized (sync) {
+ sync.wait();
+ }
+ assumeFalse(a.updateHintAllowed());
+ a.reportActualWorkDuration(DURATIONS_THREE, TIMESTAMPS_THREE);
+ verify(mNativeWrapperMock, never()).halReportActualWorkDuration(anyLong(), any(), any());
+ }
+
+ @Test
+ public void testDoHintInBackground() throws Exception {
+ HintManagerService service = createService();
+ IBinder token = new Binder();
+
+ AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
+ .createHintSession(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
+
+ service.mUidObserver.onUidStateChanged(
+ a.mUid, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND, 0, 0);
+ final Object sync = new Object();
+ FgThread.getHandler().post(() -> {
+ synchronized (sync) {
+ sync.notify();
+ }
+ });
+ synchronized (sync) {
+ sync.wait();
+ }
+ assertFalse(a.updateHintAllowed());
+ }
+
+ @Test
+ public void testDoHintInForeground() throws Exception {
+ HintManagerService service = createService();
+ IBinder token = new Binder();
+
+ AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
+ .createHintSession(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
+
+ service.mUidObserver.onUidStateChanged(
+ a.mUid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 0, 0);
+ assertTrue(a.updateHintAllowed());
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index f9c8a23bdfae..916a278a1567 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -44,6 +44,8 @@ import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_NEVER;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RESTRICTED;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
+import static android.content.pm.PackageManager.PERMISSION_DENIED;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static com.android.server.usage.AppStandbyController.DEFAULT_ELAPSED_TIME_THRESHOLDS;
import static com.android.server.usage.AppStandbyController.DEFAULT_SCREEN_TIME_THRESHOLDS;
@@ -56,6 +58,8 @@ import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
+import static org.mockito.AdditionalMatchers.not;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
@@ -127,6 +131,8 @@ public class AppStandbyControllerTests {
private static final int UID_SYSTEM_HEADLESS = 10003;
private static final String PACKAGE_WELLBEING = "com.example.wellbeing";
private static final int UID_WELLBEING = 10004;
+ private static final String PACKAGE_BACKGROUND_LOCATION = "com.example.backgroundLocation";
+ private static final int UID_BACKGROUND_LOCATION = 10005;
private static final int USER_ID = 0;
private static final int USER_ID2 = 10;
private static final UserHandle USER_HANDLE_USER2 = new UserHandle(USER_ID2);
@@ -391,7 +397,14 @@ public class AppStandbyControllerTests {
piw.packageName = PACKAGE_WELLBEING;
packages.add(piw);
+ PackageInfo pib = new PackageInfo();
+ pib.applicationInfo = new ApplicationInfo();
+ pib.applicationInfo.uid = UID_BACKGROUND_LOCATION;
+ pib.packageName = PACKAGE_BACKGROUND_LOCATION;
+ packages.add(pib);
+
doReturn(packages).when(mockPm).getInstalledPackagesAsUser(anyInt(), anyInt());
+
try {
for (int i = 0; i < packages.size(); ++i) {
PackageInfo pkg = packages.get(i);
@@ -402,6 +415,18 @@ public class AppStandbyControllerTests {
.getPackageUidAsUser(eq(pkg.packageName), anyInt(), anyInt());
doReturn(pkg.applicationInfo).when(mockPm)
.getApplicationInfo(eq(pkg.packageName), anyInt());
+
+ if (pkg.packageName.equals(PACKAGE_BACKGROUND_LOCATION)) {
+ doReturn(PERMISSION_GRANTED).when(mockPm).checkPermission(
+ eq(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION),
+ eq(pkg.packageName));
+ doReturn(PERMISSION_DENIED).when(mockPm).checkPermission(
+ not(eq(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION)),
+ eq(pkg.packageName));
+ } else {
+ doReturn(PERMISSION_DENIED).when(mockPm).checkPermission(anyString(),
+ eq(pkg.packageName));
+ }
}
} catch (PackageManager.NameNotFoundException nnfe) {}
}
@@ -1825,6 +1850,24 @@ public class AppStandbyControllerTests {
assertEquals(93 * DAY_MS, mController.mAppStandbyScreenThresholds[4]);
}
+ /**
+ * Package with ACCESS_BACKGROUND_LOCATION permission has minimum bucket
+ * STANDBY_BUCKET_FREQUENT.
+ * @throws Exception
+ */
+ @Test
+ public void testBackgroundLocationBucket() throws Exception {
+ reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime,
+ PACKAGE_BACKGROUND_LOCATION);
+ assertBucket(STANDBY_BUCKET_ACTIVE, PACKAGE_BACKGROUND_LOCATION);
+
+ mInjector.mElapsedRealtime += RESTRICTED_THRESHOLD;
+ // Make sure PACKAGE_BACKGROUND_LOCATION does not get lowered than STANDBY_BUCKET_FREQUENT.
+ mController.setAppStandbyBucket(PACKAGE_BACKGROUND_LOCATION, USER_ID, STANDBY_BUCKET_RARE,
+ REASON_MAIN_TIMEOUT);
+ assertBucket(STANDBY_BUCKET_FREQUENT, PACKAGE_BACKGROUND_LOCATION);
+ }
+
private String getAdminAppsStr(int userId) {
return getAdminAppsStr(userId, mController.getActiveAdminAppsForTest(userId));
}
diff --git a/services/tests/servicestests/src/com/android/server/uwb/OWNERS b/services/tests/servicestests/src/com/android/server/uwb/OWNERS
new file mode 100644
index 000000000000..c31a2f1ed3bc
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/uwb/OWNERS
@@ -0,0 +1 @@
+include platform/frameworks/base:/core/java/android/uwb/OWNERS
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 3ca90603e9d2..3f9caa95df4a 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
@@ -34,7 +34,7 @@ import android.content.ContextWrapper;
import android.hardware.input.IInputDevicesChangedListener;
import android.hardware.input.IInputManager;
import android.hardware.input.InputManager;
-import android.os.CombinedVibrationEffect;
+import android.os.CombinedVibration;
import android.os.Handler;
import android.os.Process;
import android.os.VibrationAttributes;
@@ -67,8 +67,8 @@ public class InputDeviceDelegateTest {
private static final String REASON = "some reason";
private static final VibrationAttributes VIBRATION_ATTRIBUTES =
new VibrationAttributes.Builder().setUsage(VibrationAttributes.USAGE_ALARM).build();
- private static final CombinedVibrationEffect SYNCED_EFFECT =
- CombinedVibrationEffect.createSynced(VibrationEffect.createOneShot(100, 255));
+ private static final CombinedVibration SYNCED_EFFECT =
+ CombinedVibration.createParallel(VibrationEffect.createOneShot(100, 255));
@Rule public MockitoRule rule = MockitoJUnit.rule();
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
index c439b9c56e74..5743982171cb 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -34,7 +34,7 @@ import static org.mockito.Mockito.when;
import android.hardware.vibrator.Braking;
import android.hardware.vibrator.IVibrator;
import android.hardware.vibrator.IVibratorManager;
-import android.os.CombinedVibrationEffect;
+import android.os.CombinedVibration;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.Process;
@@ -109,7 +109,7 @@ public class VibrationThreadTest {
public void vibrate_noVibrator_ignoresVibration() {
mVibratorProviders.clear();
long vibrationId = 1;
- CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
+ CombinedVibration effect = CombinedVibration.createParallel(
VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
waitForCompletion(thread);
@@ -122,7 +122,7 @@ public class VibrationThreadTest {
@Test
public void vibrate_missingVibrators_ignoresVibration() {
long vibrationId = 1;
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSequential()
+ CombinedVibration effect = CombinedVibration.startSequential()
.addNext(2, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.addNext(3, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
.combine();
@@ -311,7 +311,7 @@ public class VibrationThreadTest {
long vibrationId = 1;
VibrationEffect fallback = VibrationEffect.createOneShot(10, 100);
- Vibration vibration = createVibration(vibrationId, CombinedVibrationEffect.createSynced(
+ Vibration vibration = createVibration(vibrationId, CombinedVibration.createParallel(
VibrationEffect.get(VibrationEffect.EFFECT_CLICK)));
vibration.addFallback(VibrationEffect.EFFECT_CLICK, fallback);
VibrationThread thread = startThreadAndDispatcher(vibration);
@@ -498,7 +498,7 @@ public class VibrationThreadTest {
mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_TICK);
long vibrationId = 1;
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+ CombinedVibration effect = CombinedVibration.startParallel()
.addVibrator(VIBRATOR_ID, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
.addVibrator(2, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
.combine();
@@ -524,7 +524,7 @@ public class VibrationThreadTest {
mVibratorProviders.get(3).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
long vibrationId = 1;
- CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
+ CombinedVibration effect = CombinedVibration.createParallel(
VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
waitForCompletion(thread);
@@ -557,7 +557,7 @@ public class VibrationThreadTest {
VibrationEffect composed = VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
.compose();
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+ CombinedVibration effect = CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.addVibrator(2, VibrationEffect.createOneShot(10, 100))
.addVibrator(3, VibrationEffect.createWaveform(
@@ -603,7 +603,7 @@ public class VibrationThreadTest {
VibrationEffect composed = VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
.compose();
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSequential()
+ CombinedVibration effect = CombinedVibration.startSequential()
.addNext(3, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), /* delay= */ 50)
.addNext(1, VibrationEffect.createOneShot(10, 100), /* delay= */ 50)
.addNext(2, composed, /* delay= */ 50)
@@ -652,7 +652,7 @@ public class VibrationThreadTest {
VibrationEffect composed = VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 100)
.compose();
- CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(composed);
+ CombinedVibration effect = CombinedVibration.createParallel(composed);
VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
assertTrue(waitUntil(t -> !mVibratorProviders.get(1).getEffectSegments().isEmpty()
@@ -686,7 +686,7 @@ public class VibrationThreadTest {
VibrationEffect composed = VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
.compose();
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+ CombinedVibration effect = CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.addVibrator(2, VibrationEffect.createOneShot(10, 100))
.addVibrator(3, VibrationEffect.createWaveform(new long[]{10}, new int[]{100}, -1))
@@ -717,7 +717,7 @@ public class VibrationThreadTest {
when(mThreadCallbacks.prepareSyncedVibration(anyLong(), any())).thenReturn(false);
long vibrationId = 1;
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+ CombinedVibration effect = CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.createOneShot(10, 100))
.addVibrator(2, VibrationEffect.createWaveform(new long[]{5}, new int[]{200}, -1))
.combine();
@@ -746,7 +746,7 @@ public class VibrationThreadTest {
when(mThreadCallbacks.triggerSyncedVibration(anyLong())).thenReturn(false);
long vibrationId = 1;
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+ CombinedVibration effect = CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.createOneShot(10, 100))
.addVibrator(2, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.combine();
@@ -772,7 +772,7 @@ public class VibrationThreadTest {
mVibratorProviders.get(3).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
long vibrationId = 1;
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+ CombinedVibration effect = CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.createWaveform(
new long[]{5, 10, 10}, new int[]{1, 2, 3}, -1))
.addVibrator(2, VibrationEffect.createWaveform(
@@ -851,7 +851,7 @@ public class VibrationThreadTest {
mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
long vibrationId = 1;
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+ CombinedVibration effect = CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.addVibrator(2, VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
@@ -885,7 +885,7 @@ public class VibrationThreadTest {
mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
long vibrationId = 1;
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+ CombinedVibration effect = CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.createWaveform(
new long[]{100, 100}, new int[]{1, 2}, 0))
.addVibrator(2, VibrationEffect.createOneShot(100, 100))
@@ -938,11 +938,11 @@ public class VibrationThreadTest {
}
private VibrationThread startThreadAndDispatcher(long vibrationId, VibrationEffect effect) {
- return startThreadAndDispatcher(vibrationId, CombinedVibrationEffect.createSynced(effect));
+ return startThreadAndDispatcher(vibrationId, CombinedVibration.createParallel(effect));
}
private VibrationThread startThreadAndDispatcher(long vibrationId,
- CombinedVibrationEffect effect) {
+ CombinedVibration effect) {
return startThreadAndDispatcher(createVibration(vibrationId, effect));
}
@@ -982,7 +982,7 @@ public class VibrationThreadTest {
mTestLooper.dispatchAll();
}
- private Vibration createVibration(long id, CombinedVibrationEffect effect) {
+ private Vibration createVibration(long id, CombinedVibration effect) {
return new Vibration(mVibrationToken, (int) id, effect, ATTRS, UID, PACKAGE_NAME, "reason");
}
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index 12ced388d5f7..e367b7448299 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -49,7 +49,7 @@ import android.hardware.vibrator.IVibrator;
import android.hardware.vibrator.IVibratorManager;
import android.media.AudioAttributes;
import android.media.AudioManager;
-import android.os.CombinedVibrationEffect;
+import android.os.CombinedVibration;
import android.os.Handler;
import android.os.IBinder;
import android.os.IVibratorStateListener;
@@ -231,7 +231,7 @@ public class VibratorManagerServiceTest {
assertNotNull(service.getVibratorInfo(1));
assertFalse(service.isVibrating(1));
- CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
+ CombinedVibration effect = CombinedVibration.createParallel(
VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
vibrate(service, effect, HAPTIC_FEEDBACK_ATTRS);
service.cancelVibrate(service);
@@ -343,7 +343,7 @@ public class VibratorManagerServiceTest {
service.registerVibratorStateListener(i, listeners[i]);
}
- vibrate(service, CombinedVibrationEffect.startSynced()
+ vibrate(service, CombinedVibration.startParallel()
.addVibrator(0, VibrationEffect.createOneShot(40, 100))
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.combine(), ALARM_ATTRS);
@@ -361,7 +361,7 @@ public class VibratorManagerServiceTest {
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
mVibratorProviders.get(3).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
- CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
+ CombinedVibration effect = CombinedVibration.createParallel(
VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
assertTrue(createSystemReadyService().setAlwaysOnEffect(
UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
@@ -382,7 +382,7 @@ public class VibratorManagerServiceTest {
mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
mVibratorProviders.get(4).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+ CombinedVibration effect = CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK))
.addVibrator(2, VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK))
.addVibrator(3, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK))
@@ -409,7 +409,7 @@ public class VibratorManagerServiceTest {
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
mVibratorProviders.get(3).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
- CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
+ CombinedVibration effect = CombinedVibration.createParallel(
VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
assertTrue(createSystemReadyService().setAlwaysOnEffect(
UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
@@ -427,7 +427,7 @@ public class VibratorManagerServiceTest {
mockVibrators(1);
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
- CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
+ CombinedVibration effect = CombinedVibration.createParallel(
VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE));
assertFalse(createSystemReadyService().setAlwaysOnEffect(
UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
@@ -440,7 +440,7 @@ public class VibratorManagerServiceTest {
mockVibrators(1);
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSequential()
+ CombinedVibration effect = CombinedVibration.startSequential()
.addNext(0, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.combine();
assertFalse(createSystemReadyService().setAlwaysOnEffect(
@@ -454,9 +454,9 @@ public class VibratorManagerServiceTest {
mockVibrators(1);
VibratorManagerService service = createSystemReadyService();
- CombinedVibrationEffect mono = CombinedVibrationEffect.createSynced(
+ CombinedVibration mono = CombinedVibration.createParallel(
VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
- CombinedVibrationEffect stereo = CombinedVibrationEffect.startSynced()
+ CombinedVibration stereo = CombinedVibration.startParallel()
.addVibrator(0, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK))
.combine();
assertFalse(service.setAlwaysOnEffect(UID, PACKAGE_NAME, 1, mono, ALARM_ATTRS));
@@ -566,6 +566,54 @@ public class VibratorManagerServiceTest {
}
@Test
+ public void vibrate_withOngoingRepeatingVibration_ignoresEffect() throws Exception {
+ mockVibrators(1);
+ mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+ VibratorManagerService service = createSystemReadyService();
+
+ VibrationEffect repeatingEffect = VibrationEffect.createWaveform(
+ new long[]{10_000, 10_000}, new int[]{128, 255}, 1);
+ vibrate(service, repeatingEffect, new VibrationAttributes.Builder().setUsage(
+ VibrationAttributes.USAGE_UNKNOWN).build());
+
+ // VibrationThread will start this vibration async, so wait before checking it started.
+ assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getEffectSegments().isEmpty(),
+ service, TEST_TIMEOUT_MILLIS));
+
+ vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK),
+ new VibrationAttributes.Builder().setUsage(
+ VibrationAttributes.USAGE_TOUCH).build());
+
+ // Wait before checking it never played a second effect.
+ assertFalse(waitUntil(s -> mVibratorProviders.get(1).getEffectSegments().size() > 1,
+ service, /* timeout= */ 50));
+ }
+
+ @Test
+ public void vibrate_withOngoingAlarmVibration_ignoresEffect() throws Exception {
+ mockVibrators(1);
+ mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+ VibratorManagerService service = createSystemReadyService();
+
+ VibrationEffect alarmEffect = VibrationEffect.createWaveform(
+ new long[]{10_000, 10_000}, new int[]{128, 255}, -1);
+ vibrate(service, alarmEffect, new VibrationAttributes.Builder().setUsage(
+ VibrationAttributes.USAGE_ALARM).build());
+
+ // VibrationThread will start this vibration async, so wait before checking it started.
+ assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getEffectSegments().isEmpty(),
+ service, TEST_TIMEOUT_MILLIS));
+
+ vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK),
+ new VibrationAttributes.Builder().setUsage(
+ VibrationAttributes.USAGE_TOUCH).build());
+
+ // Wait before checking it never played a second effect.
+ assertFalse(waitUntil(s -> mVibratorProviders.get(1).getEffectSegments().size() > 1,
+ service, /* timeout= */ 50));
+ }
+
+ @Test
public void vibrate_withInputDevices_vibratesInputDevices() throws Exception {
mockVibrators(1);
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
@@ -576,7 +624,7 @@ public class VibratorManagerServiceTest {
setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
VibratorManagerService service = createSystemReadyService();
- CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
+ CombinedVibration effect = CombinedVibration.createParallel(
VibrationEffect.createOneShot(10, 10));
vibrate(service, effect, ALARM_ATTRS);
verify(mIInputManagerMock).vibrateCombined(eq(1), eq(effect), any());
@@ -632,7 +680,7 @@ public class VibratorManagerServiceTest {
VibrationEffect composed = VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 100)
.compose();
- CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(composed);
+ CombinedVibration effect = CombinedVibration.createParallel(composed);
// Wait for vibration to start, it should finish right away with trigger callback.
vibrate(service, effect, ALARM_ATTRS);
@@ -664,7 +712,7 @@ public class VibratorManagerServiceTest {
mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
VibratorManagerService service = createSystemReadyService();
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+ CombinedVibration effect = CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.addVibrator(2, VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
@@ -690,7 +738,7 @@ public class VibratorManagerServiceTest {
fakeVibrator1.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
VibratorManagerService service = createSystemReadyService();
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+ CombinedVibration effect = CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.addVibrator(2, VibrationEffect.createOneShot(10, 100))
.combine();
@@ -710,7 +758,7 @@ public class VibratorManagerServiceTest {
when(mNativeWrapperMock.prepareSynced(any())).thenReturn(false);
VibratorManagerService service = createSystemReadyService();
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+ CombinedVibration effect = CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.createOneShot(10, 50))
.addVibrator(2, VibrationEffect.createOneShot(10, 100))
.combine();
@@ -731,7 +779,7 @@ public class VibratorManagerServiceTest {
when(mNativeWrapperMock.triggerSynced(anyLong())).thenReturn(false);
VibratorManagerService service = createSystemReadyService();
- CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+ CombinedVibration effect = CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.createOneShot(10, 50))
.addVibrator(2, VibrationEffect.createOneShot(10, 100))
.combine();
@@ -761,22 +809,22 @@ public class VibratorManagerServiceTest {
fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
VibratorManagerService service = createSystemReadyService();
- vibrate(service, CombinedVibrationEffect.startSynced()
- .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
- .combine(), ALARM_ATTRS);
- assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 1,
- service, TEST_TIMEOUT_MILLIS));
-
- vibrate(service, CombinedVibrationEffect.startSequential()
+ vibrate(service, CombinedVibration.startSequential()
.addNext(1, VibrationEffect.createOneShot(20, 100))
.combine(), NOTIFICATION_ATTRS);
- assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 2,
+ assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 1,
service, TEST_TIMEOUT_MILLIS));
vibrate(service, VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
.compose(), HAPTIC_FEEDBACK_ATTRS);
+ assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 3,
+ service, TEST_TIMEOUT_MILLIS));
+
+ vibrate(service, CombinedVibration.startParallel()
+ .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+ .combine(), ALARM_ATTRS);
assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 4,
service, TEST_TIMEOUT_MILLIS));
@@ -785,17 +833,17 @@ public class VibratorManagerServiceTest {
assertEquals(4, fakeVibrator.getEffectSegments().size());
assertEquals(1, fakeVibrator.getAmplitudes().size());
- // Alarm vibration is always VIBRATION_INTENSITY_HIGH.
- PrebakedSegment expected = new PrebakedSegment(
- VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_STRONG);
- assertEquals(expected, fakeVibrator.getEffectSegments().get(0));
-
// Notification vibrations will be scaled with SCALE_VERY_HIGH.
assertTrue(0.6 < fakeVibrator.getAmplitudes().get(0));
// Haptic feedback vibrations will be scaled with SCALE_LOW.
- assertTrue(0.5 < ((PrimitiveSegment) fakeVibrator.getEffectSegments().get(2)).getScale());
- assertTrue(0.5 > ((PrimitiveSegment) fakeVibrator.getEffectSegments().get(3)).getScale());
+ assertTrue(0.5 < ((PrimitiveSegment) fakeVibrator.getEffectSegments().get(1)).getScale());
+ assertTrue(0.5 > ((PrimitiveSegment) fakeVibrator.getEffectSegments().get(2)).getScale());
+
+ // Alarm vibration is always VIBRATION_INTENSITY_HIGH.
+ PrebakedSegment expected = new PrebakedSegment(
+ VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_STRONG);
+ assertEquals(expected, fakeVibrator.getEffectSegments().get(3));
// Ring vibrations have intensity OFF and are not played.
}
@@ -805,7 +853,7 @@ public class VibratorManagerServiceTest {
mockVibrators(1, 2);
VibratorManagerService service = createSystemReadyService();
vibrate(service,
- CombinedVibrationEffect.startSynced()
+ CombinedVibration.startParallel()
.addVibrator(1, VibrationEffect.createOneShot(1000, 100))
.combine(),
HAPTIC_FEEDBACK_ATTRS);
@@ -893,10 +941,10 @@ public class VibratorManagerServiceTest {
private void vibrate(VibratorManagerService service, VibrationEffect effect,
VibrationAttributes attrs) {
- vibrate(service, CombinedVibrationEffect.createSynced(effect), attrs);
+ vibrate(service, CombinedVibration.createParallel(effect), attrs);
}
- private void vibrate(VibratorManagerService service, CombinedVibrationEffect effect,
+ private void vibrate(VibratorManagerService service, CombinedVibration effect,
VibrationAttributes attrs) {
service.vibrate(UID, PACKAGE_NAME, effect, attrs, "some reason", service);
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
index 27a48269f68c..c502ed5d5984 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
@@ -1416,6 +1416,18 @@ public class ManagedServicesTest extends UiServiceTestCase {
new ArraySet(Arrays.asList(new ComponentName("xml", "class"))));
}
+ @Test
+ public void loadDefaults_versionLatest_NoLoadDefaults() throws Exception {
+ resetComponentsAndPackages();
+ mDefaults.add(new ComponentName("default", "class"));
+ mDefaultsString = "xml/class";
+ mVersionString = String.valueOf(mService.DB_VERSION);
+ loadXml(mService);
+ assertEquals(mService.getDefaultComponents(),
+ new ArraySet(Arrays.asList(new ComponentName("xml", "class"))));
+ }
+
+
private void resetComponentsAndPackages() {
ArrayMap<Integer, ArrayMap<Integer, String>> empty = new ArrayMap(1);
ArrayMap<Integer, String> emptyPkgs = new ArrayMap(0);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
index 17c941179853..c11ac3a3e3a1 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
@@ -18,10 +18,12 @@ package com.android.server.notification;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -38,6 +40,8 @@ import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
+import android.testing.TestableContext;
+import android.util.ArraySet;
import android.util.IntArray;
import android.util.TypedXmlPullParser;
import android.util.Xml;
@@ -53,6 +57,7 @@ import org.mockito.MockitoAnnotations;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
public class NotificationAssistantsTest extends UiServiceTestCase {
@@ -73,6 +78,7 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
@Mock
private ManagedServices.UserProfiles mUserProfiles;
+ private TestableContext mContext = spy(getContext());
Object mLock = new Object();
@@ -82,10 +88,11 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- getContext().setMockPackageManager(mPm);
- getContext().addMockSystemService(Context.USER_SERVICE, mUm);
- mAssistants = spy(mNm.new NotificationAssistants(getContext(), mLock, mUserProfiles, miPm));
+ mContext.setMockPackageManager(mPm);
+ mContext.addMockSystemService(Context.USER_SERVICE, mUm);
+ mAssistants = spy(mNm.new NotificationAssistants(mContext, mLock, mUserProfiles, miPm));
when(mNm.getBinderService()).thenReturn(mINm);
+ mContext.ensureTestableResources();
List<ResolveInfo> approved = new ArrayList<>();
ResolveInfo resolve = new ResolveInfo();
@@ -113,6 +120,7 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
profileIds.add(10);
profileIds.add(12);
when(mUserProfiles.getCurrentProfileIds()).thenReturn(profileIds);
+ when(mNm.isNASMigrationDone(anyInt())).thenReturn(true);
}
@Test
@@ -189,4 +197,122 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
verify(mNm, never()).setNotificationAssistantAccessGrantedForUserInternal(
any(ComponentName.class), eq(mZero.id), anyBoolean(), anyBoolean());
}
+
+ @Test
+ public void testLoadDefaultsFromConfig() {
+ ComponentName oldDefaultComponent = ComponentName.unflattenFromString("package/Component1");
+ ComponentName newDefaultComponent = ComponentName.unflattenFromString("package/Component2");
+
+ doReturn(new ArraySet<>(Arrays.asList(oldDefaultComponent, newDefaultComponent)))
+ .when(mAssistants).queryPackageForServices(any(), anyInt(), anyInt());
+ // Test loadDefaultsFromConfig() add the config value to mDefaultComponents instead of
+ // mDefaultFromConfig
+ when(mContext.getResources().getString(
+ com.android.internal.R.string.config_defaultAssistantAccessComponent))
+ .thenReturn(oldDefaultComponent.flattenToString());
+ mAssistants.loadDefaultsFromConfig();
+ assertEquals(new ArraySet<>(Arrays.asList(oldDefaultComponent)),
+ mAssistants.getDefaultComponents());
+ assertNull(mAssistants.getDefaultFromConfig());
+
+ // Test loadDefaultFromConfig(false) only updates the mDefaultFromConfig
+ when(mContext.getResources().getString(
+ com.android.internal.R.string.config_defaultAssistantAccessComponent))
+ .thenReturn(newDefaultComponent.flattenToString());
+ mAssistants.loadDefaultsFromConfig(false);
+ assertEquals(new ArraySet<>(Arrays.asList(oldDefaultComponent)),
+ mAssistants.getDefaultComponents());
+ assertEquals(newDefaultComponent, mAssistants.getDefaultFromConfig());
+
+ // Test resetDefaultFromConfig updates the mDefaultComponents to new config value
+ mAssistants.resetDefaultFromConfig();
+ assertEquals(new ArraySet<>(Arrays.asList(newDefaultComponent)),
+ mAssistants.getDefaultComponents());
+ assertEquals(newDefaultComponent, mAssistants.getDefaultFromConfig());
+ }
+
+ @Test
+ public void testNASSettingUpgrade_userNotSet_differentDefaultNAS() {
+ ComponentName oldDefaultComponent = ComponentName.unflattenFromString("package/Component1");
+ ComponentName newDefaultComponent = ComponentName.unflattenFromString("package/Component2");
+
+ when(mNm.isNASMigrationDone(anyInt())).thenReturn(false);
+ doReturn(new ArraySet<>(Arrays.asList(newDefaultComponent)))
+ .when(mAssistants).queryPackageForServices(any(), anyInt(), anyInt());
+ when(mContext.getResources().getString(
+ com.android.internal.R.string.config_defaultAssistantAccessComponent))
+ .thenReturn(newDefaultComponent.flattenToString());
+
+ // User hasn't set the default NAS, set the oldNAS as the default with userSet=false here.
+ mAssistants.setPackageOrComponentEnabled(oldDefaultComponent.flattenToString(),
+ mZero.id, true, true /*enabled*/, false /*userSet*/);
+
+
+ // The migration for userSet==false happens in resetDefaultAssistantsIfNecessary
+ mAssistants.resetDefaultAssistantsIfNecessary();
+
+ // Verify the migration happened: setDefaultAssistantForUser should be called to
+ // update defaults
+ verify(mNm, times(1)).setNASMigrationDone(eq(mZero.id));
+ verify(mNm, times(1)).setDefaultAssistantForUser(eq(mZero.id));
+ assertEquals(new ArraySet<>(Arrays.asList(newDefaultComponent)),
+ mAssistants.getDefaultComponents());
+
+ when(mNm.isNASMigrationDone(anyInt())).thenReturn(true);
+
+ // Test resetDefaultAssistantsIfNecessary again since it will be called on every reboot
+ mAssistants.resetDefaultAssistantsIfNecessary();
+
+ // The migration should not happen again, the invoke time for migration should not increase
+ verify(mNm, times(1)).setNASMigrationDone(eq(mZero.id));
+ // The invoke time outside migration part should increase by 1
+ verify(mNm, times(2)).setDefaultAssistantForUser(eq(mZero.id));
+ }
+
+ @Test
+ public void testNASSettingUpgrade_userNotSet_sameDefaultNAS() {
+ ComponentName defaultComponent = ComponentName.unflattenFromString("package/Component1");
+
+ when(mNm.isNASMigrationDone(anyInt())).thenReturn(false);
+ doReturn(new ArraySet<>(Arrays.asList(defaultComponent)))
+ .when(mAssistants).queryPackageForServices(any(), anyInt(), anyInt());
+ when(mContext.getResources().getString(
+ com.android.internal.R.string.config_defaultAssistantAccessComponent))
+ .thenReturn(defaultComponent.flattenToString());
+
+ // User hasn't set the default NAS, set the oldNAS as the default with userSet=false here.
+ mAssistants.setPackageOrComponentEnabled(defaultComponent.flattenToString(),
+ mZero.id, true, true /*enabled*/, false /*userSet*/);
+
+ // The migration for userSet==false happens in resetDefaultAssistantsIfNecessary
+ mAssistants.resetDefaultAssistantsIfNecessary();
+
+ verify(mNm, times(1)).setNASMigrationDone(eq(mZero.id));
+ verify(mNm, times(1)).setDefaultAssistantForUser(eq(mZero.id));
+ assertEquals(new ArraySet<>(Arrays.asList(defaultComponent)),
+ mAssistants.getDefaultComponents());
+ }
+
+ @Test
+ public void testNASSettingUpgrade_userNotSet_defaultNASNone() {
+ ComponentName oldDefaultComponent = ComponentName.unflattenFromString("package/Component1");
+ when(mNm.isNASMigrationDone(anyInt())).thenReturn(false);
+ doReturn(new ArraySet<>(Arrays.asList(oldDefaultComponent)))
+ .when(mAssistants).queryPackageForServices(any(), anyInt(), anyInt());
+ // New default is none
+ when(mContext.getResources().getString(
+ com.android.internal.R.string.config_defaultAssistantAccessComponent))
+ .thenReturn("");
+
+ // User hasn't set the default NAS, set the oldNAS as the default with userSet=false here.
+ mAssistants.setPackageOrComponentEnabled(oldDefaultComponent.flattenToString(),
+ mZero.id, true, true /*enabled*/, false /*userSet*/);
+
+ // The migration for userSet==false happens in resetDefaultAssistantsIfNecessary
+ mAssistants.resetDefaultAssistantsIfNecessary();
+
+ verify(mNm, times(1)).setNASMigrationDone(eq(mZero.id));
+ verify(mNm, times(1)).setDefaultAssistantForUser(eq(mZero.id));
+ assertEquals(new ArraySet<>(), mAssistants.getDefaultComponents());
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 8be19f002fa5..87efaa270ec4 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -58,10 +58,13 @@ import static android.service.notification.Adjustment.KEY_USER_SENTIMENT;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
-import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_SILENT;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
+import static com.android.server.notification.NotificationManagerService.ACTION_DISABLE_NAS;
+import static com.android.server.notification.NotificationManagerService.ACTION_ENABLE_NAS;
+import static com.android.server.notification.NotificationManagerService.ACTION_LEARNMORE_NAS;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
@@ -313,6 +316,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Mock
MultiRateLimiter mToastRateLimiter;
BroadcastReceiver mPackageIntentReceiver;
+ BroadcastReceiver mNASIntentReceiver;
NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
1 << 30);
@@ -526,6 +530,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
verify(mContext, atLeastOnce()).registerReceiverAsUser(broadcastReceiverCaptor.capture(),
any(), intentFilterCaptor.capture(), any(), any());
+ verify(mContext, atLeastOnce()).registerReceiver(broadcastReceiverCaptor.capture(),
+ intentFilterCaptor.capture());
List<BroadcastReceiver> broadcastReceivers = broadcastReceiverCaptor.getAllValues();
List<IntentFilter> intentFilters = intentFilterCaptor.getAllValues();
@@ -535,10 +541,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
&& filter.hasAction(Intent.ACTION_PACKAGES_UNSUSPENDED)
&& filter.hasAction(Intent.ACTION_PACKAGES_SUSPENDED)) {
mPackageIntentReceiver = broadcastReceivers.get(i);
- break;
+ } else if (filter.hasAction(ACTION_ENABLE_NAS)
+ && filter.hasAction(ACTION_DISABLE_NAS)
+ && filter.hasAction(ACTION_LEARNMORE_NAS)) {
+ mNASIntentReceiver = broadcastReceivers.get(i);
}
}
assertNotNull("package intent receiver should exist", mPackageIntentReceiver);
+ assertNotNull("nas intent receiver should exist", mNASIntentReceiver);
// Pretend the shortcut exists
List<ShortcutInfo> shortcutInfos = new ArrayList<>();
@@ -632,6 +642,16 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mPackageIntentReceiver.onReceive(getContext(), intent);
}
+ private void simulateNASUpgradeBroadcast(String action, int uid) {
+ final Bundle extras = new Bundle();
+ extras.putInt(Intent.EXTRA_USER_ID, uid);
+
+ final Intent intent = new Intent(action);
+ intent.putExtras(extras);
+
+ mNASIntentReceiver.onReceive(getContext(), intent);
+ }
+
private ArrayMap<Boolean, ArrayList<ComponentName>> generateResetComponentValues() {
ArrayMap<Boolean, ArrayList<ComponentName>> changed = new ArrayMap<>();
changed.put(true, new ArrayList<>());
@@ -5730,6 +5750,223 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ public void testNASSettingUpgrade_userSetNull_showOnBoarding() throws RemoteException {
+ ComponentName newDefaultComponent = ComponentName.unflattenFromString("package/Component1");
+ TestableNotificationManagerService service = spy(mService);
+ int userId = 11;
+ setUsers(new int[]{userId});
+ setNASMigrationDone(false, userId);
+ when(mAssistants.getDefaultFromConfig())
+ .thenReturn(newDefaultComponent);
+ when(mAssistants.getAllowedComponents(anyInt()))
+ .thenReturn(new ArrayList<>());
+ when(mAssistants.hasUserSet(userId)).thenReturn(true);
+
+ service.migrateDefaultNASShowNotificationIfNecessary();
+ assertFalse(service.isNASMigrationDone(userId));
+ verify(service, times(1)).createNASUpgradeNotification(eq(userId));
+ verify(mAssistants, times(0)).resetDefaultFromConfig();
+
+ //Test user clear data before enable/disable from onboarding notification
+ ArrayMap<Boolean, ArrayList<ComponentName>> changedListeners =
+ generateResetComponentValues();
+ when(mListeners.resetComponents(anyString(), anyInt())).thenReturn(changedListeners);
+ ArrayMap<Boolean, ArrayList<ComponentName>> changes = new ArrayMap<>();
+ changes.put(true, new ArrayList(Arrays.asList(newDefaultComponent)));
+ changes.put(false, new ArrayList());
+ when(mAssistants.resetComponents(anyString(), anyInt())).thenReturn(changes);
+
+ //Clear data
+ service.getBinderService().clearData("package", userId, false);
+ //Test migrate flow again
+ service.migrateDefaultNASShowNotificationIfNecessary();
+
+ //The notification should be still there
+ assertFalse(service.isNASMigrationDone(userId));
+ verify(service, times(2)).createNASUpgradeNotification(eq(userId));
+ verify(mAssistants, times(0)).resetDefaultFromConfig();
+ assertEquals(null, service.getApprovedAssistant(userId));
+ }
+
+ @Test
+ public void testNASSettingUpgrade_userSetDifferentDefault_showOnboarding()
+ throws RemoteException {
+ ComponentName oldDefaultComponent = ComponentName.unflattenFromString("package/Component1");
+ ComponentName newDefaultComponent = ComponentName.unflattenFromString("package/Component2");
+ TestableNotificationManagerService service = spy(mService);
+ int userId = 11;
+ setUsers(new int[]{userId});
+ setNASMigrationDone(false, userId);
+ when(mAssistants.getDefaultComponents())
+ .thenReturn(new ArraySet<>(Arrays.asList(oldDefaultComponent)));
+ when(mAssistants.getDefaultFromConfig())
+ .thenReturn(newDefaultComponent);
+ when(mAssistants.getAllowedComponents(anyInt()))
+ .thenReturn(Arrays.asList(oldDefaultComponent));
+ when(mAssistants.hasUserSet(userId)).thenReturn(true);
+
+ service.migrateDefaultNASShowNotificationIfNecessary();
+ assertFalse(service.isNASMigrationDone(userId));
+ verify(service, times(1)).createNASUpgradeNotification(eq(userId));
+ verify(mAssistants, times(0)).resetDefaultFromConfig();
+
+ //Test user clear data before enable/disable from onboarding notification
+ ArrayMap<Boolean, ArrayList<ComponentName>> changedListeners =
+ generateResetComponentValues();
+ when(mListeners.resetComponents(anyString(), anyInt())).thenReturn(changedListeners);
+ ArrayMap<Boolean, ArrayList<ComponentName>> changes = new ArrayMap<>();
+ changes.put(true, new ArrayList(Arrays.asList(newDefaultComponent)));
+ changes.put(false, new ArrayList());
+ when(mAssistants.resetComponents(anyString(), anyInt())).thenReturn(changes);
+
+ //Clear data
+ service.getBinderService().clearData("package", userId, false);
+ //Test migrate flow again
+ service.migrateDefaultNASShowNotificationIfNecessary();
+
+ //The notification should be still there
+ assertFalse(service.isNASMigrationDone(userId));
+ verify(service, times(2)).createNASUpgradeNotification(eq(userId));
+ verify(mAssistants, times(0)).resetDefaultFromConfig();
+ assertEquals(oldDefaultComponent, service.getApprovedAssistant(userId));
+ }
+
+ @Test
+ public void testNASSettingUpgrade_multiUser() throws RemoteException {
+ ComponentName oldDefaultComponent = ComponentName.unflattenFromString("package/Component1");
+ ComponentName newDefaultComponent = ComponentName.unflattenFromString("package/Component2");
+ TestableNotificationManagerService service = spy(mService);
+ int userId1 = 11;
+ int userId2 = 12;
+ setUsers(new int[]{userId1, userId2});
+ setNASMigrationDone(false, userId1);
+ setNASMigrationDone(false, userId2);
+ when(mAssistants.getDefaultComponents())
+ .thenReturn(new ArraySet<>(Arrays.asList(oldDefaultComponent)));
+ when(mAssistants.getDefaultFromConfig())
+ .thenReturn(newDefaultComponent);
+ //User1: need onboarding
+ when(mAssistants.getAllowedComponents(userId1))
+ .thenReturn(Arrays.asList(oldDefaultComponent));
+ //User2: no onboarding
+ when(mAssistants.getAllowedComponents(userId2))
+ .thenReturn(Arrays.asList(newDefaultComponent));
+
+ when(mAssistants.hasUserSet(userId1)).thenReturn(true);
+ when(mAssistants.hasUserSet(userId2)).thenReturn(true);
+
+ service.migrateDefaultNASShowNotificationIfNecessary();
+ assertFalse(service.isNASMigrationDone(userId1));
+ assertTrue(service.isNASMigrationDone(userId2));
+
+ verify(service, times(1)).createNASUpgradeNotification(any(Integer.class));
+ // only user2's default get updated
+ verify(mAssistants, times(1)).resetDefaultFromConfig();
+ }
+
+ @Test
+ public void testNASSettingUpgrade_clearDataAfterMigrationIsDone() throws RemoteException {
+ ComponentName defaultComponent = ComponentName.unflattenFromString("package/Component");
+ TestableNotificationManagerService service = spy(mService);
+ int userId = 12;
+ setUsers(new int[]{userId});
+ when(mAssistants.getDefaultComponents())
+ .thenReturn(new ArraySet<>(Arrays.asList(defaultComponent)));
+ when(mAssistants.hasUserSet(userId)).thenReturn(true);
+ setNASMigrationDone(true, userId);
+
+ //Test User clear data
+ ArrayMap<Boolean, ArrayList<ComponentName>> changedListeners =
+ generateResetComponentValues();
+ when(mListeners.resetComponents(anyString(), anyInt())).thenReturn(changedListeners);
+ ArrayMap<Boolean, ArrayList<ComponentName>> changes = new ArrayMap<>();
+ changes.put(true, new ArrayList(Arrays.asList(defaultComponent)));
+ changes.put(false, new ArrayList());
+ when(mAssistants.resetComponents(anyString(), anyInt())).thenReturn(changes);
+
+ //Clear data
+ service.getBinderService().clearData("package", userId, false);
+ //Test migrate flow again
+ service.migrateDefaultNASShowNotificationIfNecessary();
+
+ //The notification should not appear again
+ verify(service, times(0)).createNASUpgradeNotification(eq(userId));
+ verify(mAssistants, times(0)).resetDefaultFromConfig();
+ }
+
+ @Test
+ public void testNASUpgradeNotificationDisableBroadcast() {
+ int userId = 11;
+ setUsers(new int[]{userId});
+ TestableNotificationManagerService service = spy(mService);
+ setNASMigrationDone(false, userId);
+
+ simulateNASUpgradeBroadcast(ACTION_DISABLE_NAS, userId);
+
+ assertTrue(service.isNASMigrationDone(userId));
+ // User disabled the NAS from notification, the default stored in xml should be null
+ // rather than the new default
+ verify(mAssistants, times(1)).clearDefaults();
+ verify(mAssistants, times(0)).resetDefaultFromConfig();
+
+ //No more notification after disabled
+ service.migrateDefaultNASShowNotificationIfNecessary();
+ verify(service, times(0)).createNASUpgradeNotification(eq(userId));
+ }
+
+ @Test
+ public void testNASUpgradeNotificationEnableBroadcast_multiUser() {
+ int userId1 = 11;
+ int userId2 = 12;
+ setUsers(new int[]{userId1, userId2});
+ TestableNotificationManagerService service = spy(mService);
+ setNASMigrationDone(false, userId1);
+ setNASMigrationDone(false, userId2);
+
+ simulateNASUpgradeBroadcast(ACTION_ENABLE_NAS, userId1);
+
+ assertTrue(service.isNASMigrationDone(userId1));
+ assertFalse(service.isNASMigrationDone(userId2));
+ verify(mAssistants, times(1)).resetDefaultFromConfig();
+
+ service.migrateDefaultNASShowNotificationIfNecessary();
+ verify(service, times(0)).createNASUpgradeNotification(eq(userId1));
+ }
+
+ @Test
+ public void testNASUpgradeNotificationLearnMoreBroadcast() {
+ int userId = 11;
+ setUsers(new int[]{userId});
+ TestableNotificationManagerService service = spy(mService);
+ setNASMigrationDone(false, userId);
+ doNothing().when(mContext).startActivity(any());
+
+ simulateNASUpgradeBroadcast(ACTION_LEARNMORE_NAS, userId);
+
+ verify(mContext, times(1)).startActivity(any(Intent.class));
+ assertFalse(service.isNASMigrationDone(userId));
+ verify(service, times(0)).createNASUpgradeNotification(eq(userId));
+ verify(mAssistants, times(0)).resetDefaultFromConfig();
+ }
+
+
+ private void setNASMigrationDone(boolean done, int userId) {
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.NAS_SETTINGS_UPDATED, done ? 1 : 0, userId);
+ }
+
+ private void setUsers(int[] userIds) {
+ List<UserInfo> users = new ArrayList<>();
+ for (int id: userIds) {
+ users.add(new UserInfo(id, String.valueOf(id), 0));
+ }
+ for (UserInfo user : users) {
+ when(mUm.getUserInfo(eq(user.id))).thenReturn(user);
+ }
+ when(mUm.getUsers()).thenReturn(users);
+ }
+
+ @Test
public void clearDefaultListenersPackageShouldEnableIt() throws RemoteException {
ArrayMap<Boolean, ArrayList<ComponentName>> changedAssistants =
generateResetComponentValues();
diff --git a/services/tests/wmtests/src/com/android/server/wm/InputMethodMenuControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InputMethodMenuControllerTest.java
index 78074d6e1492..1b9308d32c8c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InputMethodMenuControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InputMethodMenuControllerTest.java
@@ -77,7 +77,7 @@ public class InputMethodMenuControllerTest extends WindowTestsBase {
dc.getImeContainer(), 1000 /* ownerUid */, TYPE_INPUT_METHOD_DIALOG,
null /* options */);
return true;
- }).when(wms).registerWindowContextListener(any(), eq(TYPE_INPUT_METHOD_DIALOG),
+ }).when(wms).attachWindowContextToDisplayArea(any(), eq(TYPE_INPUT_METHOD_DIALOG),
anyInt(), any());
mSecondaryDisplay = new TestDisplayContent.Builder(mAtm, 1000, 1000).build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
index 7714a6cead1d..ee01b7fe5750 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
@@ -53,12 +53,16 @@ public class LetterboxTest {
private boolean mAreCornersRounded = false;
private int mColor = Color.BLACK;
+ private boolean mHasWallpaperBackground = false;
+ private int mBlurRadius = 0;
+ private float mDarkScrimAlpha = 0.5f;
@Before
public void setUp() throws Exception {
mSurfaces = new SurfaceControlMocker();
mLetterbox = new Letterbox(mSurfaces, StubTransaction::new,
- () -> mAreCornersRounded, () -> Color.valueOf(mColor));
+ () -> mAreCornersRounded, () -> Color.valueOf(mColor),
+ () -> mHasWallpaperBackground, () -> mBlurRadius, () -> mDarkScrimAlpha);
mTransaction = spy(StubTransaction.class);
}
@@ -190,6 +194,22 @@ public class LetterboxTest {
}
@Test
+ public void testNeedsApplySurfaceChanges_wallpaperBackgroundRequested() {
+ mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000));
+ mLetterbox.applySurfaceChanges(mTransaction);
+
+ verify(mTransaction).setAlpha(mSurfaces.top, 1.0f);
+ assertFalse(mLetterbox.needsApplySurfaceChanges());
+
+ mHasWallpaperBackground = true;
+
+ assertTrue(mLetterbox.needsApplySurfaceChanges());
+
+ mLetterbox.applySurfaceChanges(mTransaction);
+ verify(mTransaction).setAlpha(mSurfaces.top, mDarkScrimAlpha);
+ }
+
+ @Test
public void testApplySurfaceChanges_cornersNotRounded_surfaceBehindNotCreated() {
mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000));
mLetterbox.applySurfaceChanges(mTransaction);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 6ffdb099695d..5d6a5c0b5167 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -34,6 +34,7 @@ import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -754,6 +755,7 @@ public class RecentTasksTest extends WindowTestsBase {
final Task alwaysOnTopTask = taskDisplayArea.createRootTask(WINDOWING_MODE_MULTI_WINDOW,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
alwaysOnTopTask.setAlwaysOnTop(true);
+ alwaysOnTopTask.setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, true);
assertFalse("Always on top tasks should not be visible recents",
mRecentTasks.isVisibleRecentTask(alwaysOnTopTask));
@@ -1030,9 +1032,6 @@ public class RecentTasksTest extends WindowTestsBase {
assertNotRestoreTask(() -> mAtm.cancelTaskWindowTransition(taskId));
assertNotRestoreTask(
() -> mAtm.resizeTask(taskId, null /* bounds */, 0 /* resizeMode */));
- assertNotRestoreTask(
- () -> mAtm.setTaskWindowingMode(taskId, WINDOWING_MODE_FULLSCREEN,
- false/* toTop */));
}
@Test
@@ -1197,8 +1196,6 @@ public class RecentTasksTest extends WindowTestsBase {
new int[]{ACTIVITY_TYPE_UNDEFINED}));
assertSecurityException(expectCallable, () -> mAtm.removeTask(0));
assertSecurityException(expectCallable,
- () -> mAtm.setTaskWindowingMode(0, WINDOWING_MODE_UNDEFINED, true));
- assertSecurityException(expectCallable,
() -> mAtm.moveTaskToRootTask(0, INVALID_STACK_ID, true));
assertSecurityException(expectCallable, () -> mAtm.getAllRootTaskInfos());
assertSecurityException(expectCallable,
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index 7d137bcb2cff..153fd3a68e82 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -567,6 +567,37 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
}
@Test
+ public void testFadeRotationAfterAttachAndBeforeRestore_notRestoreNavImmediately() {
+ setupForShouldAttachNavBarDuringTransition();
+ final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
+ final ActivityRecord homeActivity = createHomeActivity();
+ initializeRecentsAnimationController(mController, homeActivity);
+
+ final WindowToken navToken = mDefaultDisplay.getDisplayPolicy().getNavigationBar().mToken;
+ final SurfaceControl.Transaction transaction = navToken.getPendingTransaction();
+
+ verify(mController.mStatusBar).setNavigationBarLumaSamplingEnabled(
+ mDefaultDisplay.mDisplayId, false);
+ verify(transaction).reparent(navToken.getSurfaceControl(), activity.getSurfaceControl());
+
+ final WindowContainer parent = navToken.getParent();
+ final NavBarFadeAnimationController navBarFadeAnimationController =
+ mDefaultDisplay.getDisplayPolicy().getNavBarFadeAnimationController();
+
+ FadeRotationAnimationController mockController =
+ mock(FadeRotationAnimationController.class);
+ doReturn(mockController).when(mDefaultDisplay).getFadeRotationAnimationController();
+
+ mController.cleanupAnimation(REORDER_MOVE_TO_TOP);
+ verify(mController.mStatusBar).setNavigationBarLumaSamplingEnabled(
+ mDefaultDisplay.mDisplayId, true);
+ verify(mockController).setOnShowRunnable(any());
+ verify(transaction, times(0)).reparent(navToken.getSurfaceControl(),
+ parent.getSurfaceControl());
+ verify(navBarFadeAnimationController, times(0)).fadeWindowToken(true);
+ }
+
+ @Test
public void testAttachNavBarInSplitScreenMode() {
setupForShouldAttachNavBarDuringTransition();
final ActivityRecord primary = createActivityRecordWithParentTask(mDefaultDisplay,
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 97cead1583e1..7c2cfab50821 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -1360,6 +1360,31 @@ public class SizeCompatTests extends WindowTestsBase {
}
@Test
+ public void testSandboxDisplayApis_letterboxAppNotSandboxed() {
+ // Set up a display in landscape with an unresizable app.
+ setUpDisplaySizeWithApp(2500, 1000);
+ mActivity.mDisplayContent.setSandboxDisplayApis(false /* sandboxDisplayApis */);
+ prepareUnresizable(mActivity, 1.5f, SCREEN_ORIENTATION_LANDSCAPE);
+ assertFitted();
+
+ // Activity max bounds not be sandboxed since sandboxing is disabled.
+ assertThat(mActivity.getMaxBounds()).isEqualTo(mActivity.mDisplayContent.getBounds());
+ }
+
+ @Test
+ public void testSandboxDisplayApis_letterboxAppSandboxed() {
+ // Set up a display in landscape with an unresizable app.
+ setUpDisplaySizeWithApp(2500, 1000);
+ mActivity.mDisplayContent.setSandboxDisplayApis(true /* sandboxDisplayApis */);
+ prepareUnresizable(mActivity, 1.5f, SCREEN_ORIENTATION_LANDSCAPE);
+ assertFitted();
+
+ // Activity max bounds should be sandboxed since sandboxing is enabled.
+ assertActivityMaxBoundsSandboxed();
+ }
+
+
+ @Test
public void testTaskDisplayAreaNotFillDisplay() {
setUpDisplaySizeWithApp(1400, 2800);
final DisplayContent display = mActivity.mDisplayContent;
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
index 268969db184a..73b9173ba143 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
@@ -130,35 +130,35 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
}
@Test
- public void testCanCallerRemoveListener_NullListener_ReturnFalse() {
- assertFalse(mController.assertCallerCanRemoveListener(mClientToken,
+ public void testAssertCallerCanModifyListener_NullListener_ReturnFalse() {
+ assertFalse(mController.assertCallerCanModifyListener(mClientToken,
true /* callerCanManagerAppTokens */, TEST_UID));
}
@Test
- public void testCanCallerRemoveListener_CanManageAppTokens_ReturnTrue() {
+ public void testAssertCallerCanModifyListener_CanManageAppTokens_ReturnTrue() {
mController.registerWindowContainerListener(mClientToken, mContainer, TEST_UID,
TYPE_APPLICATION_OVERLAY, null /* options */);
- assertTrue(mController.assertCallerCanRemoveListener(mClientToken,
+ assertTrue(mController.assertCallerCanModifyListener(mClientToken,
true /* callerCanManagerAppTokens */, ANOTHER_UID));
}
@Test
- public void testCanCallerRemoveListener_SameUid_ReturnTrue() {
+ public void testAssertCallerCanModifyListener_SameUid_ReturnTrue() {
mController.registerWindowContainerListener(mClientToken, mContainer, TEST_UID,
TYPE_APPLICATION_OVERLAY, null /* options */);
- assertTrue(mController.assertCallerCanRemoveListener(mClientToken,
+ assertTrue(mController.assertCallerCanModifyListener(mClientToken,
false /* callerCanManagerAppTokens */, TEST_UID));
}
@Test(expected = UnsupportedOperationException.class)
- public void testCanCallerRemoveListener_DifferentUid_ThrowException() {
+ public void testAssertCallerCanModifyListener_DifferentUid_ThrowException() {
mController.registerWindowContainerListener(mClientToken, mContainer, TEST_UID,
TYPE_APPLICATION_OVERLAY, null /* options */);
- mController.assertCallerCanRemoveListener(mClientToken,
+ mController.assertCallerCanModifyListener(mClientToken,
false /* callerCanManagerAppTokens */, ANOTHER_UID);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index baf072dbbc10..dd0c9e6d390e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -21,7 +21,9 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
@@ -37,11 +39,15 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertFalse;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import android.content.pm.PackageManager;
+import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
@@ -179,4 +185,69 @@ public class WindowManagerServiceTests extends WindowTestsBase {
assertThat(windowToken.getDisplayContent()).isEqualTo(mDefaultDisplay);
}
+
+ @Test
+ public void testAttachWindowContextToWindowToken_InvalidToken_EarlyReturn() {
+ spyOn(mWm.mWindowContextListenerController);
+
+ mWm.attachWindowContextToWindowToken(new Binder(), new Binder());
+
+ verify(mWm.mWindowContextListenerController, never()).getWindowType(any());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testAttachWindowContextToWindowToken_InvalidWindowType_ThrowException() {
+ spyOn(mWm.mWindowContextListenerController);
+
+ final WindowToken windowToken = createTestWindowToken(TYPE_INPUT_METHOD, mDefaultDisplay);
+ doReturn(INVALID_WINDOW_TYPE).when(mWm.mWindowContextListenerController)
+ .getWindowType(any());
+
+ mWm.attachWindowContextToWindowToken(new Binder(), windowToken.token);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testAttachWindowContextToWindowToken_DifferentWindowType_ThrowException() {
+ spyOn(mWm.mWindowContextListenerController);
+
+ final WindowToken windowToken = createTestWindowToken(TYPE_INPUT_METHOD, mDefaultDisplay);
+ doReturn(TYPE_APPLICATION).when(mWm.mWindowContextListenerController)
+ .getWindowType(any());
+
+ mWm.attachWindowContextToWindowToken(new Binder(), windowToken.token);
+ }
+
+ @Test
+ public void testAttachWindowContextToWindowToken_CallerNotValid_EarlyReturn() {
+ spyOn(mWm.mWindowContextListenerController);
+
+ final WindowToken windowToken = createTestWindowToken(TYPE_INPUT_METHOD, mDefaultDisplay);
+ doReturn(TYPE_INPUT_METHOD).when(mWm.mWindowContextListenerController)
+ .getWindowType(any());
+ doReturn(false).when(mWm.mWindowContextListenerController)
+ .assertCallerCanModifyListener(any(), anyBoolean(), anyInt());
+
+ mWm.attachWindowContextToWindowToken(new Binder(), windowToken.token);
+
+ verify(mWm.mWindowContextListenerController, never()).registerWindowContainerListener(
+ any(), any(), anyInt(), anyInt(), any());
+ }
+
+ @Test
+ public void testAttachWindowContextToWindowToken_CallerValid_DoRegister() {
+ spyOn(mWm.mWindowContextListenerController);
+
+ final WindowToken windowToken = createTestWindowToken(TYPE_INPUT_METHOD, mDefaultDisplay);
+ doReturn(TYPE_INPUT_METHOD).when(mWm.mWindowContextListenerController)
+ .getWindowType(any());
+ doReturn(true).when(mWm.mWindowContextListenerController)
+ .assertCallerCanModifyListener(any(), anyBoolean(), anyInt());
+
+ final IBinder clientToken = new Binder();
+ mWm.attachWindowContextToWindowToken(clientToken, windowToken.token);
+
+ verify(mWm.mWindowContextListenerController).registerWindowContainerListener(
+ eq(clientToken), eq(windowToken), anyInt(), eq(TYPE_INPUT_METHOD),
+ eq(windowToken.mOptions));
+ }
}
diff --git a/services/uwb/OWNERS b/services/uwb/OWNERS
new file mode 100644
index 000000000000..c31a2f1ed3bc
--- /dev/null
+++ b/services/uwb/OWNERS
@@ -0,0 +1 @@
+include platform/frameworks/base:/core/java/android/uwb/OWNERS
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 75c80313cd12..f0771bedc838 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -4883,11 +4883,10 @@ public class TelephonyManager {
/**
* Return the set of IMSIs that should be considered "merged together" for data usage
- * purposes. Unlike {@link #getMergedSubscriberIds()} this API merge IMSIs based on
- * subscription grouping: IMSI of those in the same group will all be returned.
- * Return the current IMSI if there is no subscription group.
- *
- * <p>Requires the calling app to have READ_PRIVILEGED_PHONE_STATE permission.
+ * purposes. This API merges IMSIs based on subscription grouping: IMSI of those in the same
+ * group will all be returned.
+ * Return the current IMSI if there is no subscription group. See
+ * {@link SubscriptionManager#createSubscriptionGroup(List)} for the definition of a group.
*
* @hide
*/
@@ -4900,7 +4899,6 @@ public class TelephonyManager {
return telephony.getMergedImsisFromGroup(getSubId(), getOpPackageName());
}
} catch (RemoteException ex) {
- } catch (NullPointerException ex) {
}
return new String[0];
}
diff --git a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
index 1e54093bf111..454d5b5266ee 100644
--- a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
+++ b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
@@ -63,8 +63,10 @@ class NetworkAgentConfigTest {
setPartialConnectivityAcceptable(false)
setUnvalidatedConnectivityAcceptable(true)
setLegacyTypeName("TEST_NETWORK")
- disableNat64Detection()
- disableProvisioningNotification()
+ if (isAtLeastS()) {
+ setNat64DetectionEnabled(false)
+ setProvisioningNotificationEnabled(false)
+ }
}.build()
assertTrue(config.isExplicitlySelected())
@@ -73,7 +75,12 @@ class NetworkAgentConfigTest {
assertFalse(config.isPartialConnectivityAcceptable())
assertTrue(config.isUnvalidatedConnectivityAcceptable())
assertEquals("TEST_NETWORK", config.getLegacyTypeName())
- assertFalse(config.isNat64DetectionEnabled())
- assertFalse(config.isProvisioningNotificationEnabled())
+ if (isAtLeastS()) {
+ assertFalse(config.isNat64DetectionEnabled())
+ assertFalse(config.isProvisioningNotificationEnabled())
+ } else {
+ assertTrue(config.isNat64DetectionEnabled())
+ assertTrue(config.isProvisioningNotificationEnabled())
+ }
}
}
diff --git a/tests/net/java/android/net/IpSecAlgorithmTest.java b/tests/net/java/android/net/IpSecAlgorithmTest.java
index 3a8d6004f66f..5bd221477412 100644
--- a/tests/net/java/android/net/IpSecAlgorithmTest.java
+++ b/tests/net/java/android/net/IpSecAlgorithmTest.java
@@ -121,7 +121,7 @@ public class IpSecAlgorithmTest {
@Test
public void testValidationForAlgosAddedInS() throws Exception {
- if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.R) {
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT <= Build.VERSION_CODES.R) {
return;
}
@@ -194,13 +194,13 @@ public class IpSecAlgorithmTest {
private static Set<String> getMandatoryAlgos() {
return CollectionUtils.filter(
ALGO_TO_REQUIRED_FIRST_SDK.keySet(),
- i -> Build.VERSION.FIRST_SDK_INT >= ALGO_TO_REQUIRED_FIRST_SDK.get(i));
+ i -> Build.VERSION.DEVICE_INITIAL_SDK_INT >= ALGO_TO_REQUIRED_FIRST_SDK.get(i));
}
private static Set<String> getOptionalAlgos() {
return CollectionUtils.filter(
ALGO_TO_REQUIRED_FIRST_SDK.keySet(),
- i -> Build.VERSION.FIRST_SDK_INT < ALGO_TO_REQUIRED_FIRST_SDK.get(i));
+ i -> Build.VERSION.DEVICE_INITIAL_SDK_INT < ALGO_TO_REQUIRED_FIRST_SDK.get(i));
}
@Test
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 3865fdfe7c68..47e4b5e4942a 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -4555,9 +4555,8 @@ public class ConnectivityServiceTest {
expectNoRequestChanged(testFactory);
testFactory.assertRequestCountEquals(0);
assertFalse(testFactory.getMyStartRequested());
- // ... and cell data to be torn down after nascent network timeout.
- cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent,
- mService.mNascentDelayMs + TEST_CALLBACK_TIMEOUT_MS);
+ // ... and cell data to be torn down immediately since it is no longer nascent.
+ cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
waitForIdle();
assertLength(1, mCm.getAllNetworks());
} finally {
@@ -11778,6 +11777,11 @@ public class ConnectivityServiceTest {
internetFactory.expectRequestRemove();
internetFactory.assertRequestCountEquals(0);
+ // Create a request that holds the upcoming wifi network.
+ final TestNetworkCallback wifiCallback = new TestNetworkCallback();
+ mCm.requestNetwork(new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(),
+ wifiCallback);
+
// Now WiFi connects and it's unmetered, but it's weaker than cell.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
@@ -11786,7 +11790,7 @@ public class ConnectivityServiceTest {
mWiFiNetworkAgent.connect(true);
// The OEM_PAID preference prefers an unmetered network to an OEM_PAID network, so
- // the oemPaidFactory can't beat this no matter how high its score.
+ // the oemPaidFactory can't beat wifi no matter how high its score.
oemPaidFactory.expectRequestRemove();
expectNoRequestChanged(internetFactory);
@@ -11797,6 +11801,7 @@ public class ConnectivityServiceTest {
// unmetered network, so the oemPaidNetworkFactory still can't beat this.
expectNoRequestChanged(oemPaidFactory);
internetFactory.expectRequestAdd();
+ mCm.unregisterNetworkCallback(wifiCallback);
}
/**
diff --git a/tests/net/java/com/android/server/connectivity/FullScoreTest.kt b/tests/net/java/com/android/server/connectivity/FullScoreTest.kt
index f0d7d86feb2f..45b575a4365d 100644
--- a/tests/net/java/com/android/server/connectivity/FullScoreTest.kt
+++ b/tests/net/java/com/android/server/connectivity/FullScoreTest.kt
@@ -56,7 +56,7 @@ class FullScoreTest {
if (vpn) addTransportType(NetworkCapabilities.TRANSPORT_VPN)
if (validated) addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
}.build()
- return mixInScore(nc, nac, false /* avoidBadWifi */)
+ return mixInScore(nc, nac, validated, false /* yieldToBadWifi */)
}
@Test
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index fec5ef39374a..d7535a958117 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -197,7 +197,7 @@ public class PermissionMonitorTest {
} else {
pkgInfo = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, new String[] {}, "");
}
- pkgInfo.applicationInfo.uid = UserHandle.getUid(user, UserHandle.getAppId(uid));
+ pkgInfo.applicationInfo.uid = user.getUid(UserHandle.getAppId(uid));
return pkgInfo;
}
@@ -390,7 +390,7 @@ public class PermissionMonitorTest {
public void expectPermission(Boolean permission, UserHandle[] users, int[] apps) {
for (final UserHandle user : users) {
for (final int app : apps) {
- final int uid = UserHandle.getUid(user, app);
+ final int uid = user.getUid(app);
if (!mApps.containsKey(uid)) {
fail("uid " + uid + " does not exist.");
}
@@ -404,7 +404,7 @@ public class PermissionMonitorTest {
public void expectNoPermission(UserHandle[] users, int[] apps) {
for (final UserHandle user : users) {
for (final int app : apps) {
- final int uid = UserHandle.getUid(user, app);
+ final int uid = user.getUid(app);
if (mApps.containsKey(uid)) {
fail("uid " + uid + " has listed permissions, expected none.");
}
@@ -502,9 +502,9 @@ public class PermissionMonitorTest {
// When MOCK_UID1 package is uninstalled and reinstalled, expect Netd to be updated
mPermissionMonitor.onPackageRemoved(
- MOCK_PACKAGE1, UserHandle.getUid(MOCK_USER1, MOCK_UID1));
+ MOCK_PACKAGE1, MOCK_USER1.getUid(MOCK_UID1));
verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1}));
- mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, UserHandle.getUid(MOCK_USER1, MOCK_UID1));
+ mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, MOCK_USER1.getUid(MOCK_UID1));
verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"),
aryEq(new int[] {MOCK_UID1}));
@@ -541,13 +541,13 @@ public class PermissionMonitorTest {
mPermissionMonitor.onVpnUidRangesAdded("tun0", vpnRange, VPN_UID);
// Newly-installed package should have uid rules added
- mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, UserHandle.getUid(MOCK_USER1, MOCK_UID1));
+ mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, MOCK_USER1.getUid(MOCK_UID1));
verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"),
aryEq(new int[] {MOCK_UID1}));
// Removed package should have its uid rules removed
mPermissionMonitor.onPackageRemoved(
- MOCK_PACKAGE1, UserHandle.getUid(MOCK_USER1, MOCK_UID1));
+ MOCK_PACKAGE1, MOCK_USER1.getUid(MOCK_UID1));
verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1}));
}
@@ -557,13 +557,13 @@ public class PermissionMonitorTest {
// called multiple times with the uid corresponding to each user.
private void addPackageForUsers(UserHandle[] users, String packageName, int uid) {
for (final UserHandle user : users) {
- mPermissionMonitor.onPackageAdded(packageName, UserHandle.getUid(user, uid));
+ mPermissionMonitor.onPackageAdded(packageName, user.getUid(uid));
}
}
private void removePackageForUsers(UserHandle[] users, String packageName, int uid) {
for (final UserHandle user : users) {
- mPermissionMonitor.onPackageRemoved(packageName, UserHandle.getUid(user, uid));
+ mPermissionMonitor.onPackageRemoved(packageName, user.getUid(uid));
}
}
diff --git a/tests/permission/src/com/android/framework/permission/tests/VibratorManagerServicePermissionTest.java b/tests/permission/src/com/android/framework/permission/tests/VibratorManagerServicePermissionTest.java
index fe6854316133..7cd2c23162fb 100644
--- a/tests/permission/src/com/android/framework/permission/tests/VibratorManagerServicePermissionTest.java
+++ b/tests/permission/src/com/android/framework/permission/tests/VibratorManagerServicePermissionTest.java
@@ -23,7 +23,7 @@ import static junit.framework.Assert.fail;
import android.Manifest;
import android.content.Context;
import android.os.Binder;
-import android.os.CombinedVibrationEffect;
+import android.os.CombinedVibration;
import android.os.IVibratorManagerService;
import android.os.IVibratorStateListener;
import android.os.Process;
@@ -50,8 +50,8 @@ import org.junit.runners.JUnit4;
public class VibratorManagerServicePermissionTest {
private static final String PACKAGE_NAME = "com.android.framework.permission.tests";
- private static final CombinedVibrationEffect EFFECT =
- CombinedVibrationEffect.createSynced(
+ private static final CombinedVibration EFFECT =
+ CombinedVibration.createParallel(
VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE));
private static final VibrationAttributes ATTRS = new VibrationAttributes.Builder()
.setUsage(VibrationAttributes.USAGE_ALARM)
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index bbc9bb600f6d..9a663436f983 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -39,6 +39,7 @@ import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.doAnswer;
@@ -59,7 +60,6 @@ import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
-import android.net.NetworkCapabilities.Transport;
import android.net.NetworkRequest;
import android.net.TelephonyNetworkSpecifier;
import android.net.vcn.IVcnStatusCallback;
@@ -657,7 +657,7 @@ public class VcnManagementServiceTest {
private void verifyMergedNetworkCapabilities(
NetworkCapabilities mergedCapabilities,
- @Transport int transportType,
+ int transportType,
boolean isVcnManaged,
boolean isRestricted) {
assertTrue(mergedCapabilities.hasTransport(transportType));
@@ -779,7 +779,7 @@ public class VcnManagementServiceTest {
.registerNetworkCallback(
eq(new NetworkRequest.Builder().clearCapabilities().build()),
captor.capture());
- captor.getValue().onCapabilitiesChanged(new Network(0), caps);
+ captor.getValue().onCapabilitiesChanged(mock(Network.class, CALLS_REAL_METHODS), caps);
}
@Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
index d08af9dd3370..ced8745e89c9 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
@@ -25,7 +25,10 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -83,31 +86,30 @@ public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase {
super.setUp();
mWifiInfo = mock(WifiInfo.class);
+ doReturn(mWifiInfo).when(mWifiInfo).makeCopy(anyLong());
}
private void verifyBuildNetworkCapabilitiesCommon(int transportType) {
- final NetworkCapabilities underlyingCaps = new NetworkCapabilities();
- underlyingCaps.addTransportType(transportType);
- underlyingCaps.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
- underlyingCaps.addCapability(NET_CAPABILITY_NOT_METERED);
- underlyingCaps.addCapability(NET_CAPABILITY_NOT_ROAMING);
+ final NetworkCapabilities.Builder capBuilder = new NetworkCapabilities.Builder();
+ capBuilder.addTransportType(transportType);
+ capBuilder.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
+ capBuilder.addCapability(NET_CAPABILITY_NOT_METERED);
+ capBuilder.addCapability(NET_CAPABILITY_NOT_ROAMING);
if (transportType == TRANSPORT_WIFI) {
- underlyingCaps.setTransportInfo(mWifiInfo);
- underlyingCaps.setOwnerUid(TEST_UID);
+ capBuilder.setTransportInfo(mWifiInfo);
+ capBuilder.setOwnerUid(TEST_UID);
} else if (transportType == TRANSPORT_CELLULAR) {
- underlyingCaps.setAdministratorUids(new int[] {TEST_UID});
- underlyingCaps.setNetworkSpecifier(
+ capBuilder.setNetworkSpecifier(
new TelephonyNetworkSpecifier(TEST_SUBSCRIPTION_ID_1));
}
-
- UnderlyingNetworkRecord record =
- new UnderlyingNetworkRecord(
- new Network(0), underlyingCaps, new LinkProperties(), false);
+ capBuilder.setAdministratorUids(new int[] {TEST_UID});
+ UnderlyingNetworkRecord record = new UnderlyingNetworkRecord(
+ mock(Network.class, CALLS_REAL_METHODS),
+ capBuilder.build(), new LinkProperties(), false);
final NetworkCapabilities vcnCaps =
VcnGatewayConnection.buildNetworkCapabilities(
VcnGatewayConnectionConfigTest.buildTestConfig(), record);
-
assertTrue(vcnCaps.hasTransport(TRANSPORT_CELLULAR));
assertTrue(vcnCaps.hasCapability(NET_CAPABILITY_NOT_METERED));
assertTrue(vcnCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
index dc73be25ffa3..98d553dab01a 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
@@ -26,6 +26,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -93,7 +94,7 @@ public class VcnGatewayConnectionTestBase {
protected static final UnderlyingNetworkRecord TEST_UNDERLYING_NETWORK_RECORD_1 =
new UnderlyingNetworkRecord(
- new Network(0),
+ mock(Network.class, CALLS_REAL_METHODS),
new NetworkCapabilities(),
new LinkProperties(),
false /* blocked */);
@@ -104,7 +105,7 @@ public class VcnGatewayConnectionTestBase {
protected static final UnderlyingNetworkRecord TEST_UNDERLYING_NETWORK_RECORD_2 =
new UnderlyingNetworkRecord(
- new Network(1),
+ mock(Network.class, CALLS_REAL_METHODS),
new NetworkCapabilities(),
new LinkProperties(),
false /* blocked */);
diff --git a/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java b/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
index c2c6200fd5f9..f943f34c9d52 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
@@ -22,8 +22,6 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
import android.annotation.NonNull;
import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.os.test.TestLooper;
@@ -36,9 +34,6 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.ArrayList;
-import java.util.List;
-
/** Tests for TelephonySubscriptionTracker */
@RunWith(AndroidJUnit4.class)
@SmallTest
@@ -46,8 +41,6 @@ public class VcnNetworkProviderTest {
private static final int TEST_SCORE_UNSATISFIED = 0;
private static final int TEST_SCORE_HIGH = 100;
private static final int TEST_PROVIDER_ID = 1;
- private static final int TEST_LEGACY_TYPE = ConnectivityManager.TYPE_MOBILE;
- private static final NetworkRequest.Type TEST_REQUEST_TYPE = NetworkRequest.Type.REQUEST;
@NonNull private final Context mContext;
@NonNull private final TestLooper mTestLooper;
@@ -94,28 +87,4 @@ public class VcnNetworkProviderTest {
mVcnNetworkProvider.onNetworkRequested(request, TEST_SCORE_UNSATISFIED, TEST_PROVIDER_ID);
verifyNoMoreInteractions(mListener);
}
-
- @Test
- public void testCachedRequestsPassedOnRegister() throws Exception {
- final List<NetworkRequest> requests = new ArrayList<>();
-
- for (int i = 0; i < 10; i++) {
- final NetworkRequest request =
- new NetworkRequest(
- new NetworkCapabilities(),
- TEST_LEGACY_TYPE,
- i /* requestId */,
- TEST_REQUEST_TYPE);
-
- requests.add(request);
- mVcnNetworkProvider.onNetworkRequested(request, i, i + 1);
- }
-
- mVcnNetworkProvider.registerListener(mListener);
- for (int i = 0; i < requests.size(); i++) {
- final NetworkRequest request = requests.get(i);
- verify(mListener).onNetworkRequested(request, i, i + 1);
- }
- verifyNoMoreInteractions(mListener);
- }
}
diff --git a/tools/fonts/Android.bp b/tools/fonts/Android.bp
new file mode 100644
index 000000000000..8ea114f1efc2
--- /dev/null
+++ b/tools/fonts/Android.bp
@@ -0,0 +1,51 @@
+// 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.
+
+python_defaults {
+ name: "fonts_python_defaults",
+ version: {
+ py2: {
+ enabled: false,
+ embedded_launcher: false,
+ },
+ py3: {
+ enabled: true,
+ embedded_launcher: true,
+ },
+ },
+}
+
+python_binary_host {
+ name: "fontchain_linter",
+ defaults: ["fonts_python_defaults"],
+ main: "fontchain_linter.py",
+ srcs: [
+ "fontchain_linter.py",
+ ],
+ libs: [
+ "fontTools",
+ ],
+}
+
+python_binary_host {
+ name: "update_font_metadata",
+ defaults: ["fonts_python_defaults"],
+ main: "update_font_metadata.py",
+ srcs: [
+ "update_font_metadata.py",
+ ],
+ libs: [
+ "fontTools",
+ ],
+}
diff --git a/wifi/OWNERS b/wifi/OWNERS
index c1c70e2eba6f..2caf9ed7a38a 100644
--- a/wifi/OWNERS
+++ b/wifi/OWNERS
@@ -2,5 +2,4 @@ set noparent
dysu@google.com
etancohen@google.com
-rpius@google.com
satk@google.com